private void HandleDirectionMove(Direction scanDirection, Vector2Int negativeEndPosition, Vector2Int positiveEndPosition, Stack <Command> tickCommands, bool canBounce) { var scanDisplacement = DirectionUtils.DirectionToDisplacement(scanDirection); var impactBlocks = DictionaryPool <Block, int> .Get(); for (var position = negativeEndPosition + scanDisplacement; position != positiveEndPosition; position += scanDisplacement) { var blocks = m_logicGameManager.Map[position.x, position.y]; foreach (var block in blocks) { if (!HasAttribute(block, AttributeCategory.Move) || !DirectionUtils.IsParallel(scanDirection, block.direction)) { continue; } var impactDirection = 1; var impactDisplacement = scanDisplacement; if (block.direction != scanDirection) { impactDirection = 2; impactDisplacement = Vector2Int.zero - scanDisplacement; } impactBlocks[block] = impactBlocks.GetOrDefault(block, 0) | impactDirection; if (HasAttribute(block, AttributeCategory.Push)) { for (var pushPosition = position + impactDisplacement; m_logicGameManager.InMap(pushPosition); pushPosition += impactDisplacement) { var pushBlocks = m_logicGameManager.Map[pushPosition.x, pushPosition.y]; var hasPush = false; foreach (var pushBlock in pushBlocks) { if (HasAttribute(pushBlock, AttributeCategory.Push)) { impactBlocks[pushBlock] = impactBlocks.GetOrDefault(pushBlock, 0) | impactDirection; hasPush = true; } } if (!hasPush) { break; } } } if (HasAttribute(block, AttributeCategory.Pull)) { for (var pullPosition = position - impactDisplacement; m_logicGameManager.InMap(pullPosition); pullPosition -= impactDisplacement) { var pullBlocks = m_logicGameManager.Map[pullPosition.x, pullPosition.y]; var hasPull = false; foreach (var pullBlock in pullBlocks) { if (HasAttribute(pullBlock, AttributeCategory.Pull)) { impactBlocks[pullBlock] = impactBlocks.GetOrDefault(pullBlock, 0) | impactDirection; hasPull = true; } } if (!hasPull) { break; } } } } } for (var position = positiveEndPosition - scanDisplacement; position != negativeEndPosition; position -= scanDisplacement) { var blocks = m_logicGameManager.Map[position.x, position.y]; foreach (var block in blocks) { if (impactBlocks.GetOrDefault(block, 0) == 3) { impactBlocks[block] = 0; } } } HandlePreMove(impactBlocks, scanDisplacement, tickCommands); { var stopPosition = positiveEndPosition - scanDisplacement; { var blocks = m_logicGameManager.Map[stopPosition.x, stopPosition.y]; foreach (var block in blocks) { var impact = 0; if (impactBlocks.TryGetValue(block, out impact)) { impactBlocks[block] &= ~1; } } } } { var stopPosition = negativeEndPosition + scanDisplacement; { var blocks = m_logicGameManager.Map[stopPosition.x, stopPosition.y]; foreach (var block in blocks) { var impact = 0; if (impactBlocks.TryGetValue(block, out impact)) { impactBlocks[block] &= ~2; } } } } for (var position = positiveEndPosition - scanDisplacement; position != negativeEndPosition + scanDisplacement; position -= scanDisplacement) { var hasStop = false; { var blocks = m_logicGameManager.Map[position.x, position.y]; foreach (var block in blocks) { if (HasAttribute(block, AttributeCategory.Stop) || HasAttribute(block, AttributeCategory.Pull) || HasAttribute(block, AttributeCategory.Push)) { if (impactBlocks.GetOrDefault(block, 0) != 1) { hasStop = true; break; } } } } if (hasStop) { var stopPosition = position - scanDisplacement; { var blocks = m_logicGameManager.Map[stopPosition.x, stopPosition.y]; foreach (var block in blocks) { var impact = 0; if (impactBlocks.TryGetValue(block, out impact)) { impactBlocks[block] &= ~1; } } } } } for (var position = negativeEndPosition + scanDisplacement; position != positiveEndPosition - scanDisplacement; position += scanDisplacement) { var hasStop = false; { var blocks = m_logicGameManager.Map[position.x, position.y]; foreach (var block in blocks) { if (HasAttribute(block, AttributeCategory.Stop) || HasAttribute(block, AttributeCategory.Pull) || HasAttribute(block, AttributeCategory.Push)) { if (impactBlocks.GetOrDefault(block, 0) != 2) { hasStop = true; break; } } } } if (hasStop) { var stopPosition = position + scanDisplacement; { var blocks = m_logicGameManager.Map[stopPosition.x, stopPosition.y]; foreach (var block in blocks) { var impact = 0; if (impactBlocks.TryGetValue(block, out impact)) { impactBlocks[block] &= ~2; } } } } } foreach (var impactBlockPair in impactBlocks) { var block = impactBlockPair.Key; var impact = impactBlockPair.Value; if (canBounce) { if (HasAttribute(block, AttributeCategory.Move) && impact == 0) { block.direction = DirectionUtils.GetOppositeDirection(block.direction); } } else { if (impact == 1) { PerformMoveBlockCommand(block, scanDirection, 1, tickCommands); } else if (impact == 2) { PerformMoveBlockCommand(block, DirectionUtils.GetOppositeDirection(scanDirection), 1, tickCommands); } } } DictionaryPool <Block, int> .Release(impactBlocks); }
public static string WrapUOHtmlColors(this string str, Color start, Color end) { if (start == end) { return(WrapUOHtmlColor(str, start)); } var t = new StringBuilder(); var tags = DictionaryPool <int, string> .AcquireObject(); var tago = false; var tagi = 0; for (var i = 0; i < str.Length; i++) { if (str[i] == '<') { tago = true; tagi = i; } else if (tago && str[i] == '>') { tago = false; } if (tago) { if (i > tagi) { t.Append(str[i]); } } else if (t.Length > 0) { tags[tagi] = t.ToString(); t.Clear(); } } t.Clear(); double n, o = 0.0; string tag, s; for (var i = 0; i < str.Length; i++) { tag = tags.GetValue(i); if (tag != null) { t.Append("<" + tag + ">"); } n = i / (double)str.Length; if (n <= 0 || n >= o + 0.05) { o = n; } s = str[i].ToString(); t.Append(o == n ? s.WrapUOHtmlColor(start.Interpolate(end, n), false) : s); } DictionaryPool <int, string> .FreeObject(tags); return(t.ToString()); }
public void PooledDictionary_Simple4() { var pool = DictionaryPool <string, int> .Create(4, 16, EqualityComparer <string> .Default); PooledDictionary_Simple_Impl(pool); }
// Internal validation // ------------------------------------------------- public override void EvaluateDynamicMaterialSlots() { var dynamicInputSlotsToCompare = DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Get(); var skippedDynamicSlots = ListPool <DynamicValueMaterialSlot> .Get(); // iterate the input slots using (var tempSlots = PooledList <MaterialSlot> .Get()) { GetInputSlots(tempSlots); foreach (var inputSlot in tempSlots) { inputSlot.hasError = false; // if there is a connection var edges = owner.GetEdges(inputSlot.slotReference).ToList(); if (!edges.Any()) { if (inputSlot is DynamicValueMaterialSlot) { skippedDynamicSlots.Add(inputSlot as DynamicValueMaterialSlot); } continue; } // get the output details var outputSlotRef = edges[0].outputSlot; var outputNode = outputSlotRef.node; if (outputNode == null) { continue; } var outputSlot = outputNode.FindOutputSlot <MaterialSlot>(outputSlotRef.slotId); if (outputSlot == null) { continue; } if (outputSlot.hasError) { inputSlot.hasError = true; continue; } var outputConcreteType = outputSlot.concreteValueType; // dynamic input... depends on output from other node. // we need to compare ALL dynamic inputs to make sure they // are compatable. if (inputSlot is DynamicValueMaterialSlot) { dynamicInputSlotsToCompare.Add((DynamicValueMaterialSlot)inputSlot, outputConcreteType); continue; } } m_MultiplyType = GetMultiplyType(dynamicInputSlotsToCompare.Values); // Resolve dynamics depending on matrix/vector configuration switch (m_MultiplyType) { // If all matrix resolve as per dynamic matrix case MultiplyType.Matrix: var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values); foreach (var dynamicKvP in dynamicInputSlotsToCompare) { dynamicKvP.Key.SetConcreteType(dynamicMatrixType); } foreach (var skippedSlot in skippedDynamicSlots) { skippedSlot.SetConcreteType(dynamicMatrixType); } break; // If mixed handle differently: // Iterate all slots and set their concretes based on their edges // Find matrix slot and convert its type to a vector type // Reiterate all slots and set non matrix slots to the vector type case MultiplyType.Mixed: foreach (var dynamicKvP in dynamicInputSlotsToCompare) { SetConcreteValueTypeFromEdge(dynamicKvP.Key); } MaterialSlot matrixSlot = GetMatrixSlot(); ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType); foreach (var dynamicKvP in dynamicInputSlotsToCompare) { if (dynamicKvP.Key != matrixSlot) { dynamicKvP.Key.SetConcreteType(vectorType); } } foreach (var skippedSlot in skippedDynamicSlots) { skippedSlot.SetConcreteType(vectorType); } break; // If all vector resolve as per dynamic vector default: var dynamicVectorType = ConvertDynamicVectorInputTypeToConcrete(dynamicInputSlotsToCompare.Values); foreach (var dynamicKvP in dynamicInputSlotsToCompare) { dynamicKvP.Key.SetConcreteType(dynamicVectorType); } foreach (var skippedSlot in skippedDynamicSlots) { skippedSlot.SetConcreteType(dynamicVectorType); } break; } tempSlots.Clear(); GetInputSlots(tempSlots); bool inputError = tempSlots.Any(x => x.hasError); if (inputError) { owner.AddConcretizationError(objectId, string.Format("Node {0} had input error", objectId)); hasError = true; } // configure the output slots now // their slotType will either be the default output slotType // or the above dynanic slotType for dynamic nodes // or error if there is an input error tempSlots.Clear(); GetOutputSlots(tempSlots); foreach (var outputSlot in tempSlots) { outputSlot.hasError = false; if (inputError) { outputSlot.hasError = true; continue; } if (outputSlot is DynamicValueMaterialSlot) { // Apply similar logic to output slot switch (m_MultiplyType) { // As per dynamic matrix case MultiplyType.Matrix: var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values); (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicMatrixType); break; // Mixed configuration // Find matrix slot and convert type to vector // Set output concrete to vector case MultiplyType.Mixed: MaterialSlot matrixSlot = GetMatrixSlot(); ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType); (outputSlot as DynamicValueMaterialSlot).SetConcreteType(vectorType); break; // As per dynamic vector default: var dynamicVectorType = ConvertDynamicVectorInputTypeToConcrete(dynamicInputSlotsToCompare.Values); (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicVectorType); break; } continue; } } tempSlots.Clear(); GetOutputSlots(tempSlots); if (tempSlots.Any(x => x.hasError)) { owner.AddConcretizationError(objectId, string.Format("Node {0} had output error", objectId)); hasError = true; } } CalculateNodeHasError(); ListPool <DynamicValueMaterialSlot> .Release(skippedDynamicSlots); DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare); }
/// <summary> /// Runs distribution algorithm on input. /// </summary> /// <param name="input"></param> /// <param name="output"></param> /// <param name="available">The amount you want to distribute</param> /// <returns>The overflow</returns> public static float ReqDistribute(List <DistributionInput> input, List <DistributionResult> output, float available) { List <TObject> tmp = ListPool <TObject> .Get(); List <TObject> objs = ListPool <TObject> .Get(); Dictionary <TObject, float> distributed = DictionaryPool <TObject, float> .Get(); Dictionary <TObject, float> requested = DictionaryPool <TObject, float> .Get(); float availablePrev = -available; // Parse foreach (var inp in input) { if (Mathf.Approximately(inp.requestedAmount, 0)) { continue; } distributed.Add(inp.obj, 0); requested.Add(inp.obj, inp.requestedAmount); objs.Add(inp.obj); } int panic = 0; while (available > 0 && !Mathf.Approximately(available, availablePrev) && requested.Count > 0) { availablePrev = available; float perInput = available / (float)requested.Count; foreach (var obj in objs) { float alreadyDistributed = distributed[obj]; float stillRequested = requested[obj]; float distributing = Mathf.Min(stillRequested, perInput); distributed[obj] += distributing; requested[obj] -= distributing; available -= distributing; if (Mathf.Approximately(requested[obj], 0)) { tmp.Add(obj); } } foreach (var obj in tmp) { objs.Remove(obj); requested.Remove(obj); } tmp.Clear(); panic++; if (panic > 1000) { Debug.LogError("Distribution alrogithm triggered panic exit!"); return(available); } } // Write back foreach (var kvp in distributed) { output.Add(new DistributionResult() { amount = kvp.Value, obj = kvp.Key }); } DictionaryPool <TObject, float> .Return(distributed); DictionaryPool <TObject, float> .Return(requested); ListPool <TObject> .Return(tmp); ListPool <TObject> .Return(objs); return(available); }
// Internal validation // ------------------------------------------------- public override void ValidateNode() { var isInError = false; var errorMessage = k_validationErrorMessage; var dynamicInputSlotsToCompare = DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Get(); var skippedDynamicSlots = ListPool <DynamicValueMaterialSlot> .Get(); // iterate the input slots s_TempSlots.Clear(); GetInputSlots(s_TempSlots); foreach (var inputSlot in s_TempSlots) { inputSlot.hasError = false; // if there is a connection var edges = owner.GetEdges(inputSlot.slotReference).ToList(); if (!edges.Any()) { if (inputSlot is DynamicValueMaterialSlot) { skippedDynamicSlots.Add(inputSlot as DynamicValueMaterialSlot); } continue; } // get the output details var outputSlotRef = edges[0].outputSlot; var outputNode = owner.GetNodeFromGuid(outputSlotRef.nodeGuid); if (outputNode == null) { continue; } var outputSlot = outputNode.FindOutputSlot <MaterialSlot>(outputSlotRef.slotId); if (outputSlot == null) { continue; } if (outputSlot.hasError) { inputSlot.hasError = true; continue; } var outputConcreteType = outputSlot.concreteValueType; // dynamic input... depends on output from other node. // we need to compare ALL dynamic inputs to make sure they // are compatable. if (inputSlot is DynamicValueMaterialSlot) { dynamicInputSlotsToCompare.Add((DynamicValueMaterialSlot)inputSlot, outputConcreteType); continue; } // if we have a standard connection... just check the types work! if (!ImplicitConversionExists(outputConcreteType, inputSlot.concreteValueType)) { inputSlot.hasError = true; } } m_MultiplyType = GetMultiplyType(dynamicInputSlotsToCompare.Values); // Resolve dynamics depending on matrix/vector configuration switch (m_MultiplyType) { // If all matrix resolve as per dynamic matrix case MultiplyType.Matrix: var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values); foreach (var dynamicKvP in dynamicInputSlotsToCompare) { dynamicKvP.Key.SetConcreteType(dynamicMatrixType); } foreach (var skippedSlot in skippedDynamicSlots) { skippedSlot.SetConcreteType(dynamicMatrixType); } break; // If mixed handle differently: // Iterate all slots and set their concretes based on their edges // Find matrix slot and convert its type to a vector type // Reiterate all slots and set non matrix slots to the vector type case MultiplyType.Mixed: foreach (var dynamicKvP in dynamicInputSlotsToCompare) { SetConcreteValueTypeFromEdge(dynamicKvP.Key); } MaterialSlot matrixSlot = GetMatrixSlot(); ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType); foreach (var dynamicKvP in dynamicInputSlotsToCompare) { if (dynamicKvP.Key != matrixSlot) { dynamicKvP.Key.SetConcreteType(vectorType); } } foreach (var skippedSlot in skippedDynamicSlots) { skippedSlot.SetConcreteType(vectorType); } break; // If all vector resolve as per dynamic vector default: var dynamicVectorType = ConvertDynamicInputTypeToConcrete(dynamicInputSlotsToCompare.Values); foreach (var dynamicKvP in dynamicInputSlotsToCompare) { dynamicKvP.Key.SetConcreteType(dynamicVectorType); } foreach (var skippedSlot in skippedDynamicSlots) { skippedSlot.SetConcreteType(dynamicVectorType); } break; } s_TempSlots.Clear(); GetInputSlots(s_TempSlots); var inputError = s_TempSlots.Any(x => x.hasError); // configure the output slots now // their slotType will either be the default output slotType // or the above dynanic slotType for dynamic nodes // or error if there is an input error s_TempSlots.Clear(); GetOutputSlots(s_TempSlots); foreach (var outputSlot in s_TempSlots) { outputSlot.hasError = false; if (inputError) { outputSlot.hasError = true; continue; } if (outputSlot is DynamicValueMaterialSlot) { // Apply similar logic to output slot switch (m_MultiplyType) { // As per dynamic matrix case MultiplyType.Matrix: var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values); (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicMatrixType); break; // Mixed configuration // Find matrix slot and convert type to vector // Set output concrete to vector case MultiplyType.Mixed: MaterialSlot matrixSlot = GetMatrixSlot(); ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType); (outputSlot as DynamicValueMaterialSlot).SetConcreteType(vectorType); break; // As per dynamic vector default: var dynamicVectorType = ConvertDynamicInputTypeToConcrete(dynamicInputSlotsToCompare.Values); (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicVectorType); break; } continue; } } isInError |= inputError; s_TempSlots.Clear(); GetOutputSlots(s_TempSlots); isInError |= s_TempSlots.Any(x => x.hasError); isInError |= CalculateNodeHasError(ref errorMessage); hasError = isInError; if (isInError) { ((GraphData)owner).AddValidationError(tempId, errorMessage); } else { ++version; } ListPool <DynamicValueMaterialSlot> .Release(skippedDynamicSlots); DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare); }
public void Recycle() { DictionaryPool <KeyType, ObjectType, PoolIdentifier> .Free(this); }
/// <summary> /// Applies decor values from the database. /// </summary> internal static void ApplyDatabase(DecorReimaginedOptions options) { DecorDbEntry[] entries = null; try { // Read in database from the embedded config json using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream( "ReimaginationTeam.DecorRework.buildings.json")) { var jr = new JsonTextReader(new StreamReader(stream)); entries = new JsonSerializer { MaxDepth = 2 }.Deserialize <DecorDbEntry[]>(jr); jr.Close(); } } catch (JsonException e) { // Error when loading decor PUtil.LogExcWarn(e); } catch (IOException e) { // Error when loading decor PUtil.LogExcWarn(e); } if (entries != null) { var editDecor = DictionaryPool <string, DecorDbEntry, DecorDbEntry> .Allocate(); var tileLayer = PGameUtils.GetObjectLayer(nameof(ObjectLayer.FoundationTile), ObjectLayer.FoundationTile); string id; // Add to dictionary, way faster foreach (var entry in entries) { if (!string.IsNullOrEmpty(id = entry.id) && !editDecor.ContainsKey(id)) { editDecor.Add(id, entry); } } foreach (var def in Assets.BuildingDefs) { // If PreserveTileDecor is set to true, ignore foundation tile decor mods if (editDecor.TryGetValue(id = def.PrefabID, out DecorDbEntry entry) && (def.TileLayer != tileLayer || !options.PreserveTileDecor)) { float decor = entry.decor; int radius = entry.radius; var provider = def.BuildingComplete.GetComponent <DecorProvider>(); // For reference, these do not alter the BuildingComplete def.BaseDecor = decor; def.BaseDecorRadius = radius; // Actual decor provider if (provider != null) { PUtil.LogDebug("Patched: {0} Decor: {1:F1} Radius: {2:D}".F(id, decor, radius)); provider.baseDecor = decor; provider.baseRadius = radius; } } } editDecor.Recycle(); } // Patch in the debris decor var baseOreTemplate = typeof(EntityTemplates).GetFieldSafe("baseOreTemplate", true)?.GetValue(null) as GameObject; DecorProvider component; if (baseOreTemplate != null && (component = baseOreTemplate. GetComponent <DecorProvider>()) != null) { int radius = Math.Max(1, options.DebrisRadius); component.baseDecor = options.DebrisDecor; component.baseRadius = radius; PUtil.LogDebug("Debris: {0:F1} radius {1:D}".F(options.DebrisDecor, radius)); } // Patch the suits PUtil.LogDebug("Snazzy Suit: {0:D} Warm/Cool Vest: {1:D}".F(options. SnazzySuitDecor, options.VestDecor)); ClothingWearer.ClothingInfo.FANCY_CLOTHING.decorMod = options.SnazzySuitDecor; ClothingWearer.ClothingInfo.COOL_CLOTHING.decorMod = options.VestDecor; ClothingWearer.ClothingInfo.WARM_CLOTHING.decorMod = options.VestDecor; }
public static void PickAllNonAlloc(List <ProbeHit> hits, ProbeFilter filter, SceneView sceneView, Vector2 guiPosition, int limit = DefaultLimit) { var screenPosition = HandleUtility.GUIPointToScreenPixelCoordinate(guiPosition); var ray3D = HandleUtility.GUIPointToWorldRay(guiPosition); var worldPosition = sceneView.camera.ScreenToWorldPoint(screenPosition); var layerMask = PeekPlugin.Configuration.probeLayerMask; var raycastHits = ArrayPool <RaycastHit> .New(limit); var overlapHits = ArrayPool <Collider2D> .New(limit); var handleHits = HashSetPool <GameObject> .New(); var ancestorHits = HashSetPool <ProbeHit> .New(); #if PROBUILDER_4_OR_NEWER var proBuilderHits = ListPool <ProbeHit> .New(); #endif var gameObjectHits = DictionaryPool <GameObject, ProbeHit> .New(); try { // Raycast (3D) if (filter.raycast) { var raycastHitCount = Physics.RaycastNonAlloc(ray3D, raycastHits, Mathf.Infinity, layerMask); for (var i = 0; i < raycastHitCount; i++) { var raycastHit = raycastHits[i]; #if UNITY_2019_2_OR_NEWER if (SceneVisibilityManager.instance.IsHidden(raycastHit.transform.gameObject)) { continue; } #endif var gameObject = raycastHit.transform.gameObject; if (!gameObjectHits.TryGetValue(gameObject, out var hit)) { hit = new ProbeHit(gameObject); } hit.point = raycastHit.point; hit.distance = raycastHit.distance; gameObjectHits[gameObject] = hit; } } // Overlap (2D) if (filter.overlap) { var overlapHitCount = Physics2D.OverlapPointNonAlloc(worldPosition, overlapHits, layerMask); for (var i = 0; i < overlapHitCount; i++) { var overlapHit = overlapHits[i]; #if UNITY_2019_2_OR_NEWER if (SceneVisibilityManager.instance.IsHidden(overlapHit.transform.gameObject)) { continue; } #endif var gameObject = overlapHit.transform.gameObject; if (!gameObjectHits.TryGetValue(gameObject, out var hit)) { hit = new ProbeHit(gameObject); } hit.distance = hit.distance ?? Vector3.Distance(overlapHit.transform.position, worldPosition); gameObjectHits[gameObject] = hit; } } // Handles (Editor Default) if (filter.handles && canPickHandles) { PickAllHandlesNonAlloc(handleHits, guiPosition, limit); foreach (var handleHit in handleHits) { var gameObject = handleHit; if (!gameObjectHits.TryGetValue(gameObject, out var hit)) { hit = new ProbeHit(gameObject); } hit.distance = hit.distance ?? Vector3.Distance(handleHit.transform.position, worldPosition); gameObjectHits[gameObject] = hit; } } // Ancestors foreach (var gameObjectHit in gameObjectHits) { var gameObject = gameObjectHit.Key; var hit = gameObjectHit.Value; var parent = gameObject.transform.parent; int depth = 0; while (parent != null) { var parentGameObject = parent.gameObject; var parentHit = new ProbeHit(parentGameObject); parentHit.groupGameObject = gameObject; parentHit.distance = hit.distance ?? Vector3.Distance(parentHit.transform.position, worldPosition); parentHit.groupOrder = 1000 + depth; ancestorHits.Add(parentHit); parent = parent.parent; depth++; } } #if PROBUILDER_4_OR_NEWER // ProBuilder if (filter.proBuilder && ProBuilderEditor.instance != null) { var proBuilderMeshes = ListPool <ProBuilderMesh> .New(); try { foreach (var gameObjectHit in gameObjectHits.Values) { var proBuilderMesh = gameObjectHit.gameObject.GetComponent <ProBuilderMesh>(); if (proBuilderMesh != null) { proBuilderMeshes.Add(proBuilderMesh); } } PickProBuilderElementsNonAlloc(proBuilderHits, proBuilderMeshes, sceneView, guiPosition); } finally { proBuilderMeshes.Free(); } } #endif // Prepare final hits hits.Clear(); // Add hits foreach (var gameObjectHit in gameObjectHits.Values) { hits.Add(gameObjectHit); } foreach (var ancestorHit in ancestorHits) { hits.Add(ancestorHit); } #if PROBUILDER_4_OR_NEWER foreach (var proBuilderHit in proBuilderHits) { hits.Add(proBuilderHit); } #endif // Sort by distance hits.Sort(compareHits); } finally { raycastHits.Free(); overlapHits.Free(); handleHits.Free(); ancestorHits.Free(); #if PROBUILDER_4_OR_NEWER proBuilderHits.Free(); #endif gameObjectHits.Free(); } }
/// <summary> /// Applied before UpdatePickups runs. A more optimized UpdatePickups whose aggregate /// runtime on a test world dropped from ~60 ms/1000 ms to ~45 ms/1000 ms. /// </summary> internal static bool BeforeUpdatePickups(FetchManager.FetchablesByPrefabId __instance, Navigator worker_navigator, GameObject worker_go) { var canBePickedUp = Allocate(); var pathCosts = DictionaryPool <int, int, FetchManager> .Allocate(); var finalPickups = __instance.finalPickups; // Will reflect the changes from Waste Not, Want Not and No Manual Delivery var comparer = FetchManager.ComparerIncludingPriority; bool needThreadSafe = FastTrackOptions.Instance.PickupOpts; var fetchables = __instance.fetchables.GetDataList(); int n = fetchables.Count; for (int i = 0; i < n; i++) { var fetchable = fetchables[i]; var target = fetchable.pickupable; int cell = target.cachedCell; if (target.CouldBePickedUpByMinion(worker_go)) { // Look for cell cost, share costs across multiple queries to a cell // If this is being run synchronous, no issue, otherwise the GSP patch will // avoid races on the scene partitioner if (!pathCosts.TryGetValue(cell, out int cost)) { if (needThreadSafe) { worker_navigator.GetNavigationCostNU(target, cell, out cost); } else { cost = worker_navigator.GetNavigationCost(target); } pathCosts.Add(cell, cost); } // Exclude unreachable items if (cost >= 0) { int hash = fetchable.tagBitsHash; var key = new PickupTagKey(hash, target.KPrefabID); var candidate = new FetchManager.Pickup { pickupable = target, tagBitsHash = hash, PathCost = (ushort)cost, masterPriority = fetchable.masterPriority, freshness = fetchable. freshness, foodQuality = fetchable.foodQuality }; if (canBePickedUp.TryGetValue(key, out FetchManager.Pickup current)) { // Is the new one better? int result = comparer.Compare(candidate, current); if (result < 0 || (result == 0 && candidate.pickupable. UnreservedAmount > current.pickupable.UnreservedAmount)) { canBePickedUp[key] = candidate; } } else { canBePickedUp.Add(key, candidate); } } } } // Copy the remaining pickups to the list, there are now way fewer because only // one was kept per possible tag bits (with the highest priority, best path cost, // etc) finalPickups.Clear(); foreach (var pickup in canBePickedUp.Values) { finalPickups.Add(pickup); } pathCosts.Recycle(); Recycle(canBePickedUp); // Prevent the original method from running return(false); }
public void Dispose() { DictionaryPool.Release(Dictionary); }
internal static PooledDictionary <TKey, TValue> Make() { return(new PooledDictionary <TKey, TValue>(DictionaryPool.Get())); }
public void RegisterReplacementsForNames(params string[] origNames) { var needsTranslation = ListPool <string> .Get(); try { needsTranslation.Capacity = origNames.Length; var fastReplacements = DictionaryPool <string, string> .Get(); try { foreach (var origString in origNames) { if (TranslationHelper.TryTranslateName(NameScope.DefaultNameScope, origString, out var translatedString)) { //fastReplacements[origString] = origString; fastReplacements[translatedString] = translatedString; } else { needsTranslation.Add(origString); } } if (fastReplacements.Count > 0) { RegisterReplacementStrings(fastReplacements); } } finally { DictionaryPool <string, string> .Release(fastReplacements); } foreach (var toTranslate in needsTranslation) { void ResultHandler(ITranslationResult result) { var replacements = DictionaryPool <string, string> .Get(); try { if (!TranslationHelper.NameNeedsTranslation(toTranslate, NameScope.DefaultNameScope)) { replacements[toTranslate] = toTranslate; } if (result.Succeeded) { replacements[result.TranslatedText] = result.TranslatedText; } RegisterReplacementStrings(replacements); } finally { DictionaryPool <string, string> .Release(replacements); } } GeBoAPI.Instance.AutoTranslationHelper.TranslateAsync(toTranslate, NameScope.DefaultNameScope.TranslationScope, ResultHandler); } } finally { ListPool <string> .Release(needsTranslation); } }
public void SendMetricsEvent() { ListPool <string, Manager> .PooledList pooledList = ListPool <string, Manager> .Allocate(); foreach (Mod mod in mods) { if (mod.enabled) { pooledList.Add(mod.title); } } DictionaryPool <string, object, Manager> .PooledDictionary pooledDictionary = DictionaryPool <string, object, Manager> .Allocate(); pooledDictionary["ModCount"] = pooledList.Count; pooledDictionary["Mods"] = pooledList; ThreadedHttps <KleiMetrics> .Instance.SendEvent(pooledDictionary); pooledDictionary.Recycle(); pooledList.Recycle(); KCrashReporter.haveActiveMods = (pooledList.Count > 0); }
protected void OnEnable() { m_isExpandedById = DictionaryPool <string, bool> .Get(); OnEnableEntityStoreEditor(); }
public override void EvaluateDynamicMaterialSlots() { var dynamicInputSlotsToCompare = DictionaryPool <DynamicVectorMaterialSlot, ConcreteSlotValueType> .Get(); var skippedDynamicSlots = ListPool <DynamicVectorMaterialSlot> .Get(); var dynamicMatrixInputSlotsToCompare = DictionaryPool <DynamicMatrixMaterialSlot, ConcreteSlotValueType> .Get(); var skippedDynamicMatrixSlots = ListPool <DynamicMatrixMaterialSlot> .Get(); // iterate the input slots using (var tempSlots = PooledList <MaterialSlot> .Get()) { GetInputSlots(tempSlots); foreach (var inputSlot in tempSlots) { inputSlot.hasError = false; // if there is a connection var edges = owner.GetEdges(inputSlot.slotReference).ToList(); if (!edges.Any()) { if (inputSlot is DynamicVectorMaterialSlot) { skippedDynamicSlots.Add(inputSlot as DynamicVectorMaterialSlot); } if (inputSlot is DynamicMatrixMaterialSlot) { skippedDynamicMatrixSlots.Add(inputSlot as DynamicMatrixMaterialSlot); } continue; } // get the output details var outputSlotRef = edges[0].outputSlot; var outputNode = outputSlotRef.node; if (outputNode == null) { continue; } var outputSlot = outputNode.FindOutputSlot <MaterialSlot>(outputSlotRef.slotId); if (outputSlot == null) { continue; } if (outputSlot.hasError) { inputSlot.hasError = true; continue; } var outputConcreteType = outputSlot.concreteValueType; // dynamic input... depends on output from other node. // we need to compare ALL dynamic inputs to make sure they // are compatable. if (inputSlot is DynamicVectorMaterialSlot) { dynamicInputSlotsToCompare.Add((DynamicVectorMaterialSlot)inputSlot, outputConcreteType); continue; } else if (inputSlot is DynamicMatrixMaterialSlot) { dynamicMatrixInputSlotsToCompare.Add((DynamicMatrixMaterialSlot)inputSlot, outputConcreteType); continue; } } // and now dynamic matrices var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicMatrixInputSlotsToCompare.Values); foreach (var dynamicKvP in dynamicMatrixInputSlotsToCompare) { dynamicKvP.Key.SetConcreteType(dynamicMatrixType); } foreach (var skippedSlot in skippedDynamicMatrixSlots) { skippedSlot.SetConcreteType(dynamicMatrixType); } // we can now figure out the dynamic slotType // from here set all the var dynamicType = SlotValueHelper.ConvertMatrixToVectorType(dynamicMatrixType); foreach (var dynamicKvP in dynamicInputSlotsToCompare) { dynamicKvP.Key.SetConcreteType(dynamicType); } foreach (var skippedSlot in skippedDynamicSlots) { skippedSlot.SetConcreteType(dynamicType); } tempSlots.Clear(); GetInputSlots(tempSlots); bool inputError = tempSlots.Any(x => x.hasError); if (inputError) { owner.AddConcretizationError(objectId, string.Format("Node {0} had input error", objectId)); hasError = true; } // configure the output slots now // their slotType will either be the default output slotType // or the above dynanic slotType for dynamic nodes // or error if there is an input error tempSlots.Clear(); GetOutputSlots(tempSlots); foreach (var outputSlot in tempSlots) { outputSlot.hasError = false; if (inputError) { outputSlot.hasError = true; continue; } if (outputSlot is DynamicVectorMaterialSlot) { (outputSlot as DynamicVectorMaterialSlot).SetConcreteType(dynamicType); continue; } else if (outputSlot is DynamicMatrixMaterialSlot) { (outputSlot as DynamicMatrixMaterialSlot).SetConcreteType(dynamicMatrixType); continue; } } tempSlots.Clear(); GetOutputSlots(tempSlots); if (tempSlots.Any(x => x.hasError)) { owner.AddConcretizationError(objectId, string.Format("Node {0} had output error", objectId)); hasError = true; } } CalculateNodeHasError(); ListPool <DynamicVectorMaterialSlot> .Release(skippedDynamicSlots); DictionaryPool <DynamicVectorMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare); ListPool <DynamicMatrixMaterialSlot> .Release(skippedDynamicMatrixSlots); DictionaryPool <DynamicMatrixMaterialSlot, ConcreteSlotValueType> .Release(dynamicMatrixInputSlotsToCompare); }
internal static GenericMenu BuildPopupList(Object target, UnityEventBase dummyEvent, SerializedProperty listener) { //special case for components... we want all the game objects targets there! var targetToUse = target; if (targetToUse is Component) { targetToUse = (target as Component).gameObject; } // find the current event target... var methodName = listener.FindPropertyRelative(kMethodNamePath); var menu = new GenericMenu(); menu.AddItem(new GUIContent(kNoFunctionString), string.IsNullOrEmpty(methodName.stringValue), ClearEventFunction, new UnityEventFunction(listener, null, null, PersistentListenerMode.EventDefined)); if (targetToUse == null) { return(menu); } menu.AddSeparator(""); // figure out the signature of this delegate... // The property at this stage points to the 'container' and has the field name Type delegateType = dummyEvent.GetType(); // check out the signature of invoke as this is the callback! MethodInfo delegateMethod = delegateType.GetMethod("Invoke"); var delegateArgumentsTypes = delegateMethod.GetParameters().Select(x => x.ParameterType).ToArray(); var duplicateNames = DictionaryPool <string, int> .Get(); var duplicateFullNames = DictionaryPool <string, int> .Get(); GeneratePopUpForType(menu, targetToUse, targetToUse.GetType().Name, listener, delegateArgumentsTypes); duplicateNames[targetToUse.GetType().Name] = 0; if (targetToUse is GameObject) { Component[] comps = (targetToUse as GameObject).GetComponents <Component>(); // Collect all the names and record how many times the same name is used. foreach (Component comp in comps) { var duplicateIndex = 0; if (duplicateNames.TryGetValue(comp.GetType().Name, out duplicateIndex)) { duplicateIndex++; } duplicateNames[comp.GetType().Name] = duplicateIndex; } foreach (Component comp in comps) { if (comp == null) { continue; } var compType = comp.GetType(); string targetName = compType.Name; int duplicateIndex = 0; // Is this name used multiple times? If so then use the full name plus an index if there are also duplicates of this. (case 1309997) if (duplicateNames[compType.Name] > 0) { if (duplicateFullNames.TryGetValue(compType.FullName, out duplicateIndex)) { targetName = $"{compType.FullName} ({duplicateIndex})"; } else { targetName = compType.FullName; } } GeneratePopUpForType(menu, comp, targetName, listener, delegateArgumentsTypes); duplicateFullNames[compType.FullName] = duplicateIndex + 1; } DictionaryPool <string, int> .Release(duplicateNames); DictionaryPool <string, int> .Release(duplicateFullNames); } return(menu); }
public void Render1000ms(float dt) { DictionaryPool <int, ListPool <FetchList2, FetchListStatusItemUpdater> .PooledList, FetchListStatusItemUpdater> .PooledDictionary pooledDictionary = DictionaryPool <int, ListPool <FetchList2, FetchListStatusItemUpdater> .PooledList, FetchListStatusItemUpdater> .Allocate(); foreach (FetchList2 fetchList in fetchLists) { if (!((Object)fetchList.Destination == (Object)null)) { ListPool <FetchList2, FetchListStatusItemUpdater> .PooledList value = null; int instanceID = fetchList.Destination.GetInstanceID(); if (!pooledDictionary.TryGetValue(instanceID, out value)) { value = (pooledDictionary[instanceID] = ListPool <FetchList2, FetchListStatusItemUpdater> .Allocate()); } value.Add(fetchList); } } DictionaryPool <Tag, float, FetchListStatusItemUpdater> .PooledDictionary pooledDictionary2 = DictionaryPool <Tag, float, FetchListStatusItemUpdater> .Allocate(); DictionaryPool <Tag, float, FetchListStatusItemUpdater> .PooledDictionary pooledDictionary3 = DictionaryPool <Tag, float, FetchListStatusItemUpdater> .Allocate(); foreach (KeyValuePair <int, ListPool <FetchList2, FetchListStatusItemUpdater> .PooledList> item in pooledDictionary) { ListPool <Tag, FetchListStatusItemUpdater> .PooledList pooledList2 = ListPool <Tag, FetchListStatusItemUpdater> .Allocate(); Storage destination = item.Value[0].Destination; foreach (FetchList2 item2 in item.Value) { item2.UpdateRemaining(); Dictionary <Tag, float> remaining = item2.GetRemaining(); foreach (KeyValuePair <Tag, float> item3 in remaining) { if (!pooledList2.Contains(item3.Key)) { pooledList2.Add(item3.Key); } } } ListPool <Pickupable, FetchListStatusItemUpdater> .PooledList pooledList3 = ListPool <Pickupable, FetchListStatusItemUpdater> .Allocate(); foreach (GameObject item4 in destination.items) { if (!((Object)item4 == (Object)null)) { Pickupable component = item4.GetComponent <Pickupable>(); if (!((Object)component == (Object)null)) { pooledList3.Add(component); } } } DictionaryPool <Tag, float, FetchListStatusItemUpdater> .PooledDictionary pooledDictionary4 = DictionaryPool <Tag, float, FetchListStatusItemUpdater> .Allocate(); foreach (Tag item5 in pooledList2) { float num = 0f; foreach (Pickupable item6 in pooledList3) { if (item6.KPrefabID.HasTag(item5)) { num += item6.TotalAmount; } } pooledDictionary4[item5] = num; } foreach (Tag item7 in pooledList2) { if (!pooledDictionary2.ContainsKey(item7)) { pooledDictionary2[item7] = WorldInventory.Instance.GetTotalAmount(item7); } if (!pooledDictionary3.ContainsKey(item7)) { pooledDictionary3[item7] = WorldInventory.Instance.GetAmount(item7); } } foreach (FetchList2 item8 in item.Value) { bool should_add = false; bool should_add2 = true; bool should_add3 = false; Dictionary <Tag, float> remaining2 = item8.GetRemaining(); foreach (KeyValuePair <Tag, float> item9 in remaining2) { Tag key = item9.Key; float value2 = item9.Value; float num2 = pooledDictionary4[key]; float b = pooledDictionary2[key]; float num3 = pooledDictionary3[key]; float num4 = Mathf.Min(value2, b); float num5 = num3 + num4; float minimumAmount = item8.GetMinimumAmount(key); if (num2 + num5 < minimumAmount) { should_add = true; } if (num5 < value2) { should_add2 = false; } if (num2 + num5 > value2 && value2 > num5) { should_add3 = true; } } item8.UpdateStatusItem(Db.Get().BuildingStatusItems.WaitingForMaterials, ref item8.waitingForMaterialsHandle, should_add2); item8.UpdateStatusItem(Db.Get().BuildingStatusItems.MaterialsUnavailable, ref item8.materialsUnavailableHandle, should_add); item8.UpdateStatusItem(Db.Get().BuildingStatusItems.MaterialsUnavailableForRefill, ref item8.materialsUnavailableForRefillHandle, should_add3); } pooledDictionary4.Recycle(); pooledList3.Recycle(); pooledList2.Recycle(); item.Value.Recycle(); } pooledDictionary3.Recycle(); pooledDictionary2.Recycle(); pooledDictionary.Recycle(); }
private void UpdateOpenOrders() { ComplexRecipe[] recipes = GetRecipes(); if (recipes.Length != openOrderCounts.Count) { Debug.LogErrorFormat(base.gameObject, "Recipe count {0} doesn't match open order count {1}", recipes.Length, openOrderCounts.Count); } bool flag = false; hasOpenOrders = false; for (int i = 0; i < recipes.Length; i++) { ComplexRecipe recipe = recipes[i]; int recipePrefetchCount = GetRecipePrefetchCount(recipe); if (recipePrefetchCount > 0) { hasOpenOrders = true; } int num = openOrderCounts[i]; if (num != recipePrefetchCount) { if (recipePrefetchCount < num) { flag = true; } openOrderCounts[i] = recipePrefetchCount; } } DictionaryPool <Tag, float, ComplexFabricator> .PooledDictionary pooledDictionary = DictionaryPool <Tag, float, ComplexFabricator> .Allocate(); DictionaryPool <Tag, float, ComplexFabricator> .PooledDictionary pooledDictionary2 = DictionaryPool <Tag, float, ComplexFabricator> .Allocate(); for (int j = 0; j < openOrderCounts.Count; j++) { int num2 = openOrderCounts[j]; if (num2 > 0) { ComplexRecipe complexRecipe = recipe_list[j]; ComplexRecipe.RecipeElement[] ingredients = complexRecipe.ingredients; ComplexRecipe.RecipeElement[] array = ingredients; foreach (ComplexRecipe.RecipeElement recipeElement in array) { pooledDictionary[recipeElement.material] = inStorage.GetAmountAvailable(recipeElement.material); } } } for (int l = 0; l < recipe_list.Length; l++) { int num3 = openOrderCounts[l]; if (num3 > 0) { ComplexRecipe complexRecipe2 = recipe_list[l]; ComplexRecipe.RecipeElement[] ingredients2 = complexRecipe2.ingredients; ComplexRecipe.RecipeElement[] array2 = ingredients2; foreach (ComplexRecipe.RecipeElement recipeElement2 in array2) { float num4 = recipeElement2.amount * (float)num3; float num5 = num4 - pooledDictionary[recipeElement2.material]; if (num5 > 0f) { pooledDictionary2.TryGetValue(recipeElement2.material, out float value); pooledDictionary2[recipeElement2.material] = value + num5; pooledDictionary[recipeElement2.material] = 0f; } else { DictionaryPool <Tag, float, ComplexFabricator> .PooledDictionary pooledDictionary3; Tag material; (pooledDictionary3 = pooledDictionary)[material = recipeElement2.material] = pooledDictionary3[material] - num4; } } } } if (flag) { CancelFetches(); } if (pooledDictionary2.Count > 0) { UpdateFetches(pooledDictionary2); } UpdateMaterialNeeds(pooledDictionary2); pooledDictionary2.Recycle(); pooledDictionary.Recycle(); }
private static void FreeHUpdateUI() { // for 3P the character names show in one extra place that the standard check doesn't cover. // easiest to just update each time. var freeHScene = Object.FindObjectOfType <FreeHScene>(); if (freeHScene == null) { return; } var member = Traverse.Create(freeHScene).Field <FreeHScene.Member>("member")?.Value; if (member == null) { return; } Action <string> GetUpdateUIField(string fieldName) { void Callback(string value) { if (string.IsNullOrEmpty(value) || freeHScene == null) { return; } var field = Traverse.Create(freeHScene).Field <TextMeshProUGUI>(fieldName)?.Value; if (field == null) { return; } field.text = value; } return(Callback); } Action <string> GetUpdateTextCallback(string path) { void Callback(string value) { if (string.IsNullOrEmpty(value)) { return; } var obj = GameObject.Find(path); if (obj == null) { return; } var uiText = obj.GetComponent <Text>(); if (uiText == null) { return; } uiText.text = value; } return(Callback); } var callbackMap = DictionaryPool <SaveData.Heroine, List <Action <string> > > .Get(); try { if (member.resultHeroine.HasValue && member.resultHeroine.Value != null) { if (!callbackMap.TryGetValue(member.resultHeroine.Value, out var callbacks)) { callbackMap[member.resultHeroine.Value] = callbacks = GeBoCommon.Utilities.ListPool <Action <string> > .Get(); } callbacks.Add(GetUpdateUIField("textFemaleName1")); } if (member.resultPartner.HasValue && member.resultPartner.Value != null) { if (!callbackMap.TryGetValue(member.resultPartner.Value, out var callbacks)) { callbackMap[member.resultPartner.Value] = callbacks = GeBoCommon.Utilities.ListPool <Action <string> > .Get(); } callbacks.Add(GetUpdateUIField("textFemaleName2")); } // leaving traverse to work with earlier versions var resultDarkHeroine = Traverse.Create(member) .Field <ReactiveProperty <SaveData.Heroine> >("resultDarkHeroine")?.Value; if (resultDarkHeroine != null && resultDarkHeroine.HasValue && resultDarkHeroine.Value != null) { if (!callbackMap.TryGetValue(resultDarkHeroine.Value, out var callbacks)) { callbackMap[resultDarkHeroine.Value] = callbacks = GeBoCommon.Utilities.ListPool <Action <string> > .Get(); } callbacks.Add( // ReSharper disable once StringLiteralTypo GetUpdateTextCallback("/FreeHScene/Canvas/Panel/Dark/FemaleInfomation/Name/TextMeshPro Text")); } foreach (var entry in callbackMap) { foreach (var heroineChaFile in entry.Key.GetRelatedChaFiles()) { heroineChaFile.TranslateFullName( translated => { foreach (var callback in entry.Value) { try { callback(translated); } catch (Exception err) { Logger.LogException(err, freeHScene, nameof(FreeHUpdateUI)); } } }); } } } finally { foreach (var entry in callbackMap) { GeBoCommon.Utilities.ListPool <Action <string> > .Release(entry.Value); } DictionaryPool <SaveData.Heroine, List <Action <string> > > .Release(callbackMap); } }
/// <summary> /// The better and more optimized UpdatePickups. Aggregate runtime on a test world /// dropped from ~60 ms/1000 ms to ~45 ms/1000 ms. /// </summary> private static void UpdatePickups(FetchManager.FetchablesByPrefabId targets, Navigator navigator, GameObject worker) { var canBePickedUp = DictionaryPool <PickupTagKey, FetchManager.Pickup, FetchManager> .Allocate(); var pathCosts = DictionaryPool <int, int, FetchManager> .Allocate(); var finalPickups = targets.finalPickups; // Will reflect the changes from Waste Not, Want Not and No Manual Delivery var comparer = PICKUP_COMPARER.Get(null); foreach (var fetchable in targets.fetchables.GetDataList()) { var target = fetchable.pickupable; int cell = target.cachedCell; if (target.CouldBePickedUpByMinion(worker)) { // Look for cell cost, share costs across multiple queries to a cell if (!pathCosts.TryGetValue(cell, out int cost)) { pathCosts.Add(cell, cost = target.GetNavigationCost(navigator, cell)); } // Exclude unreachable items if (cost >= 0) { int hash = fetchable.tagBitsHash; var key = new PickupTagKey(hash, target.KPrefabID); var candidate = new FetchManager.Pickup { pickupable = target, tagBitsHash = hash, PathCost = (ushort)cost, masterPriority = fetchable.masterPriority, freshness = fetchable. freshness, foodQuality = fetchable.foodQuality }; if (canBePickedUp.TryGetValue(key, out FetchManager.Pickup current)) { // Is the new one better? int result = comparer.Compare(current, candidate); if (result > 0 || (result == 0 && candidate.pickupable. UnreservedAmount > current.pickupable.UnreservedAmount)) { canBePickedUp[key] = candidate; } } else { canBePickedUp.Add(key, candidate); } } } } // Copy the remaining pickups to the list, there are now way fewer because only // one was kept per possible tag bits (with the highest priority, best path cost, // etc) finalPickups.Clear(); foreach (var pair in canBePickedUp) { finalPickups.Add(pair.Value); } pathCosts.Recycle(); canBePickedUp.Recycle(); }
public void PooledDictionary_Simple3() { var pool = DictionaryPool <string, int> .Create(4, 16); PooledDictionary_Simple_Impl(pool); }
public SuperGumpLayout() { _Entries = DictionaryPool <String, Action> .AcquireObject(); }
internal static void ExportSelected(LocaleIdentifier source, string dir, string name, XliffVersion version, Dictionary <StringTableCollection, HashSet <int> > collectionsWithSelectedIndexes, ITaskReporter reporter = null) { var documents = DictionaryPool <LocaleIdentifier, IXliffDocument> .Get(); try { // Used for reporting int totalTasks = collectionsWithSelectedIndexes.Sum(c => c.Value.Count); float taskStep = 1.0f / (totalTasks * 2.0f); float progress = 0; reporter?.Start($"Exporting {totalTasks} String Tables to XLIFF", string.Empty); foreach (var kvp in collectionsWithSelectedIndexes) { var stringTableCollection = kvp.Key; var sourceTable = stringTableCollection.GetTable(source) as StringTable; if (sourceTable == null) { var message = $"Collection {stringTableCollection.TableCollectionName} does not contain a table for the source language {source}"; reporter?.Fail(message); throw new Exception(message); } foreach (var stringTableIndex in kvp.Value) { var stringTable = stringTableCollection.StringTables[stringTableIndex]; reporter?.ReportProgress($"Generating document for {stringTable.name}", progress); progress += taskStep; if (!documents.TryGetValue(stringTable.LocaleIdentifier, out var targetDoc)) { targetDoc = CreateDocument(source, stringTable.LocaleIdentifier, version); documents[stringTable.LocaleIdentifier] = targetDoc; } AddTableToDocument(targetDoc, sourceTable, stringTable); } } // Now write the files foreach (var doc in documents) { var cleanName = CleanFileName(name); var fileName = $"{cleanName}_{doc.Key.Code}.xlf"; var filePath = Path.Combine(dir, fileName); reporter?.ReportProgress($"Writing {fileName}", progress); progress += taskStep; using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write)) { doc.Value.Serialize(stream); } } reporter?.Completed($"Finished exporting"); } catch (Exception e) { reporter?.Fail(e.Message); throw; } finally { DictionaryPool <LocaleIdentifier, IXliffDocument> .Release(documents); } }
public List <Callback> GenerateDependencyGraph() { var callbacks = GetCallbacks(); var packageLookup = DictionaryPool <string, List <Callback> > .Get(); var assemblyLookup = DictionaryPool <string, List <Callback> > .Get(); var classLookup = DictionaryPool <Type, Callback> .Get(); // First generate our lookups for class, assembly and package. foreach (var cb in callbacks) { classLookup[cb.classType] = cb; var assemblyName = cb.classType.Assembly.GetName().Name; if (!assemblyLookup.TryGetValue(assemblyName, out var assemblies)) { assemblies = new List <Callback>(); assemblyLookup[assemblyName] = assemblies; } assemblies.Add(cb); var package = cb.packageName; if (package != null) { if (!packageLookup.TryGetValue(package, out var packages)) { packages = new List <Callback>(); packageLookup[package] = packages; } packages.Add(cb); } } // Sort the methods so that the output order is deterministic. callbacks.Sort(); // Now connect the dependency graph nodes foreach (var dependency in callbacks) { // Dependency by class foreach (var runAfter in dependency.GetCustomAttributes <RunAfterClassAttribute>()) { // Ignore classes that may not exist in the project if (runAfter.classType == null) { continue; } if (classLookup.TryGetValue(runAfter.classType, out var runAfterMethodInfo)) { dependency.AddIncomingConnection(runAfterMethodInfo); } } foreach (var runBefore in dependency.GetCustomAttributes <RunBeforeClassAttribute>()) { // Ignore classes that may not exist in the project if (runBefore.classType == null) { continue; } if (classLookup.TryGetValue(runBefore.classType, out var runBeforeMethodInfo)) { dependency.AddOutgoingConnection(runBeforeMethodInfo); } } // Dependency by package foreach (var runAfter in dependency.GetCustomAttributes <RunAfterPackageAttribute>()) { if (packageLookup.TryGetValue(runAfter.packageName, out var runAfterMethodInfos)) { dependency.AddIncomingConnections(runAfterMethodInfos); } } foreach (var runBefore in dependency.GetCustomAttributes <RunBeforePackageAttribute>()) { if (packageLookup.TryGetValue(runBefore.packageName, out var runBeforeMethodInfos)) { dependency.AddOutgoingConnections(runBeforeMethodInfos); } } // Dependency by Assembly foreach (var runAfter in dependency.GetCustomAttributes <RunAfterAssemblyAttribute>()) { if (assemblyLookup.TryGetValue(runAfter.assemblyName, out var runAfterMethodInfos)) { dependency.AddIncomingConnections(runAfterMethodInfos); } } foreach (var runBefore in dependency.GetCustomAttributes <RunBeforeAssemblyAttribute>()) { if (assemblyLookup.TryGetValue(runBefore.assemblyName, out var runBeforeMethodInfos)) { dependency.AddOutgoingConnections(runBeforeMethodInfos); } } } DictionaryPool <string, List <Callback> > .Release(packageLookup); DictionaryPool <string, List <Callback> > .Release(assemblyLookup); DictionaryPool <Type, Callback> .Release(classLookup); return(callbacks); }
public virtual void ValidateNode() { var isInError = false; var errorMessage = k_validationErrorMessage; var dynamicInputSlotsToCompare = DictionaryPool <DynamicVectorMaterialSlot, ConcreteSlotValueType> .Get(); var skippedDynamicSlots = ListPool <DynamicVectorMaterialSlot> .Get(); var dynamicMatrixInputSlotsToCompare = DictionaryPool <DynamicMatrixMaterialSlot, ConcreteSlotValueType> .Get(); var skippedDynamicMatrixSlots = ListPool <DynamicMatrixMaterialSlot> .Get(); // iterate the input slots s_TempSlots.Clear(); GetInputSlots(s_TempSlots); foreach (var inputSlot in s_TempSlots) { inputSlot.hasError = false; // if there is a connection var edges = owner.GetEdges(inputSlot.slotReference).ToList(); if (!edges.Any()) { if (inputSlot is DynamicVectorMaterialSlot) { skippedDynamicSlots.Add(inputSlot as DynamicVectorMaterialSlot); } if (inputSlot is DynamicMatrixMaterialSlot) { skippedDynamicMatrixSlots.Add(inputSlot as DynamicMatrixMaterialSlot); } continue; } // get the output details var outputSlotRef = edges[0].outputSlot; var outputNode = owner.GetNodeFromGuid(outputSlotRef.nodeGuid); if (outputNode == null) { continue; } var outputSlot = outputNode.FindOutputSlot <MaterialSlot>(outputSlotRef.slotId); if (outputSlot == null) { continue; } if (outputSlot.hasError) { inputSlot.hasError = true; continue; } var outputConcreteType = outputSlot.concreteValueType; // dynamic input... depends on output from other node. // we need to compare ALL dynamic inputs to make sure they // are compatible. if (inputSlot is DynamicVectorMaterialSlot) { dynamicInputSlotsToCompare.Add((DynamicVectorMaterialSlot)inputSlot, outputConcreteType); continue; } else if (inputSlot is DynamicMatrixMaterialSlot) { dynamicMatrixInputSlotsToCompare.Add((DynamicMatrixMaterialSlot)inputSlot, outputConcreteType); continue; } // if we have a standard connection... just check the types work! if (!ImplicitConversionExists(outputConcreteType, inputSlot.concreteValueType)) { inputSlot.hasError = true; } } // we can now figure out the dynamic slotType // from here set all the var dynamicType = ConvertDynamicInputTypeToConcrete(dynamicInputSlotsToCompare.Values); foreach (var dynamicKvP in dynamicInputSlotsToCompare) { dynamicKvP.Key.SetConcreteType(dynamicType); } foreach (var skippedSlot in skippedDynamicSlots) { skippedSlot.SetConcreteType(dynamicType); } // and now dynamic matrices var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicMatrixInputSlotsToCompare.Values); foreach (var dynamicKvP in dynamicMatrixInputSlotsToCompare) { dynamicKvP.Key.SetConcreteType(dynamicMatrixType); } foreach (var skippedSlot in skippedDynamicMatrixSlots) { skippedSlot.SetConcreteType(dynamicMatrixType); } s_TempSlots.Clear(); GetInputSlots(s_TempSlots); var inputError = s_TempSlots.Any(x => x.hasError); // configure the output slots now // their slotType will either be the default output slotType // or the above dynamic slotType for dynamic nodes // or error if there is an input error s_TempSlots.Clear(); GetOutputSlots(s_TempSlots); foreach (var outputSlot in s_TempSlots) { outputSlot.hasError = false; if (inputError) { outputSlot.hasError = true; continue; } if (outputSlot is DynamicVectorMaterialSlot) { (outputSlot as DynamicVectorMaterialSlot).SetConcreteType(dynamicType); continue; } else if (outputSlot is DynamicMatrixMaterialSlot) { (outputSlot as DynamicMatrixMaterialSlot).SetConcreteType(dynamicMatrixType); continue; } } isInError |= inputError; s_TempSlots.Clear(); GetOutputSlots(s_TempSlots); isInError |= s_TempSlots.Any(x => x.hasError); isInError |= CalculateNodeHasError(ref errorMessage); hasError = isInError; if (isInError) { ((GraphData)owner).AddValidationError(tempId, errorMessage); } else { ++version; } ListPool <DynamicVectorMaterialSlot> .Release(skippedDynamicSlots); DictionaryPool <DynamicVectorMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare); ListPool <DynamicMatrixMaterialSlot> .Release(skippedDynamicMatrixSlots); DictionaryPool <DynamicMatrixMaterialSlot, ConcreteSlotValueType> .Release(dynamicMatrixInputSlotsToCompare); }
private void HandleDirectionYou(Direction moveDirection, Vector2Int negativeEndPosition, Vector2Int positiveEndPosition, Stack <Command> tickCommands) { var displacement = DirectionUtils.DirectionToDisplacement(moveDirection); var impactBlocks = DictionaryPool <Block, int> .Get(); for (var position = negativeEndPosition + displacement; position != positiveEndPosition; position += displacement) { var hasYou = false; { var blocks = m_logicGameManager.Map[position.x, position.y]; foreach (var block in blocks) { if (HasAttribute(block, AttributeCategory.You)) { impactBlocks[block] = impactBlocks.GetOrDefault(block, 0) | 1; hasYou = true; } } } if (hasYou) { for (var pullPosition = position - displacement; m_logicGameManager.InMap(pullPosition); pullPosition -= displacement) { var blocks = m_logicGameManager.Map[pullPosition.x, pullPosition.y]; var hasPull = false; foreach (var block in blocks) { if (HasAttribute(block, AttributeCategory.Pull)) { impactBlocks[block] = impactBlocks.GetOrDefault(block, 0) | 1; hasPull = true; } } if (!hasPull) { break; } } for (var pushPosition = position + displacement; m_logicGameManager.InMap(pushPosition); pushPosition += displacement) { var blocks = m_logicGameManager.Map[pushPosition.x, pushPosition.y]; var hasPush = false; foreach (var block in blocks) { if (HasAttribute(block, AttributeCategory.Push)) { impactBlocks[block] = impactBlocks.GetOrDefault(block, 0) | 1; hasPush = true; } } if (!hasPush) { break; } } } } HandlePreMove(impactBlocks, displacement, tickCommands); { var stopPosition = positiveEndPosition - displacement; { var blocks = m_logicGameManager.Map[stopPosition.x, stopPosition.y]; foreach (var block in blocks) { var impact = 0; if (impactBlocks.TryGetValue(block, out impact)) { impactBlocks[block] = 0; } } } } for (var position = positiveEndPosition - displacement; position != negativeEndPosition + displacement; position -= displacement) { var hasStop = false; { var blocks = m_logicGameManager.Map[position.x, position.y]; foreach (var block in blocks) { if (HasAttribute(block, AttributeCategory.Stop) || HasAttribute(block, AttributeCategory.Pull) || HasAttribute(block, AttributeCategory.Push)) { if (impactBlocks.GetOrDefault(block, 0) == 0) { hasStop = true; break; } } } } if (hasStop) { var stopPosition = position - displacement; { var blocks = m_logicGameManager.Map[stopPosition.x, stopPosition.y]; foreach (var block in blocks) { var impact = 0; if (impactBlocks.TryGetValue(block, out impact)) { impactBlocks[block] = 0; } } } } } foreach (var impactBlockPair in impactBlocks) { var block = impactBlockPair.Key; var impact = impactBlockPair.Value; if (impact == 1) { PerformMoveBlockCommand(block, moveDirection, 1, tickCommands); } } DictionaryPool <Block, int> .Release(impactBlocks); }