Changeset - 339712c9aa0a
[Not reviewed]
default
0 1 0
Jason Maltzen (jmaltzen) - 9 years ago 2015-12-26 04:08:57
jason.maltzen@unsanctioned.net
Fix up a crash that can happen one resume if ingredients are disabled between recipe generation runs.
1 file changed with 8 insertions and 5 deletions:
0 comments (0 inline, 0 general)
RecipeGenerator.cs
Show inline comments
...
 
@@ -225,49 +225,49 @@ namespace DesertPaintLab
 
                --nextReagentPos;
 
            }
 

	
 
            public void ReplaceLastReagent(uint reagentIdx)
 
            {
 
                uint oldReagentIdx = reagents[nextReagentPos-1];
 
                ReleaseReagent(oldReagentIdx);
 
                reagents[nextReagentPos-1] = reagentIdx;
 
                if (costSortedReagents[(int)oldReagentIdx].IsCatalyst)
 
                {
 
                    --CatalystCount;
 
                }
 
                if (costSortedReagents[(int)reagentIdx].IsCatalyst)
 
                {
 
                    ++CatalystCount;
 
                }
 
            }
 

	
 
            public uint NextFreeReagent(uint startIdx)
 
            {
 
                uint idx = startIdx;
 
                for (; idx < costSortedReagents.Count; ++idx)
 
                {
 
                    bool inUse = reagentInUse[idx];
 
                    if (inUse == false)
 
                    if ((inUse == false) && (costSortedReagents[(int)idx].Enabled))
 
                    {
 
                        //Console.WriteLine("Found free reagent idx {0}", idx);
 
                        reagentInUse[idx] = true;
 
                        return idx;
 
                    }
 
                }
 
                //Console.WriteLine("Failed to find free reagent.");
 
                return (uint)costSortedReagents.Count;
 
            }
 
    
 
            private void ReleaseReagent(uint reagentIdx)
 
            {
 
                reagentInUse[reagentIdx] = false;
 
            }
 
    
 
            public bool AddNextReagent()
 
            {
 
                bool ok = (nextReagentPos < MaxReagents);
 
                if (ok)
 
                {
 
                    uint nextReagent = NextFreeReagent(0);
 
                    reagents[nextReagentPos++] = nextReagent;
 
                    if (costSortedReagents[(int)nextReagent].IsCatalyst)
 
                    {
...
 
@@ -363,50 +363,53 @@ namespace DesertPaintLab
 
                        {
 
                            case "Reagents":
 
                                {
 
                                    //int reagentCount = int.Parse(match.Groups[2].Value);
 
                                    for (int i = 0; i < reagents.Length; ++i)
 
                                    {
 
                                        reagents[i] = INVALID_REAGENT;
 
                                        reagentInUse[i] = false;
 
                                    }
 
                                    nextReagentPos = 0;
 
                                }
 
                                break;
 
                            case "Reagent":
 
                                {
 
                                    Match reagentInfo = reagentPartsRegex.Match(match.Groups[2].Value);
 
                                    if (reagentInfo.Success)
 
                                    {
 
                                        uint reagentId = uint.Parse(reagentInfo.Groups["id"].Value);
 
                                        int isInUse = int.Parse(reagentInfo.Groups["inUse"].Value);
 
                                        uint weight = uint.Parse(reagentInfo.Groups["weight"].Value);
 
                                        reagents[nextReagentPos] = reagentId;
 
                                        currentWeights[nextReagentPos] = weight;
 
                                        if (isInUse != 0)
 
                                        {
 
                                            if (reagentId != INVALID_REAGENT)
 
                                            {
 
                                            reagentInUse[reagentId] = true;
 
                                        }
 
                                        }
 
                                        ++nextReagentPos;
 
                                    }
 
                                    else
 
                                    {
 
                                        success = false;
 
                                    }
 
                                }
 
                                break;
 
                            case "CurrentTargetQuantity":
 
                                {
 
                                    uint value = uint.Parse(match.Groups[2].Value);
 
                                    CurrentTargetQuantity = value;
 
                                }
 
                                break;
 
                            case "MaxQuantity":
 
                                {
 
                                    uint value = uint.Parse(match.Groups[2].Value);
 
                                    MaxQuantity = value;
 
                                }
 
                                break;
 
                            case "MaxReagents":
 
                                {
 
                                    uint value = uint.Parse(match.Groups[2].Value);
 
                                    MaxReagents = value;
...
 
@@ -519,102 +522,102 @@ namespace DesertPaintLab
 
            {
 
                return (int)reagent1.Cost - (int)reagent2.Cost;
 
            }
 
        }
 

	
 
        public void InitRecipes(SortedDictionary<string, PaintRecipe> initialRecipes)
 
        {
 
            if (running)
 
            {
 
                return;
 
            }
 
            foreach (PaintRecipe recipe in initialRecipes.Values)
 
            {
 
                //PaintRecipe recipeCopy = new PaintRecipe(recipe);
 
                AddCheapestRecipe(recipe);
 
            }
 
        }
 

	
 
        private void InitSortedReagents()
 
        {
 
            costSortedReagents.Clear();
 
            foreach (string name in ReagentManager.Names)
 
            {
 
                Reagent reagent = ReagentManager.GetReagent(name);
 
                if (reagent.Enabled)
 
                {
 
                    costSortedReagents.Add(reagent);
 
                }
 
            }
 
            costSortedReagents.Sort(new ReagentCostSort());
 
        }
 

	
 
        public void BeginRecipeGeneration(uint maxQuantity, uint maxReagents, uint fullQuantityDepth, uint fullQuantity)
 
        {
 
            if (running)
 
            {
 
                // Already running - don't start again
 
                return;
 
            }
 

	
 
            //this.maxQuantity = maxQuantity;
 
            this.maxReagents = maxReagents;
 
            this.fullQuantity = fullQuantity;
 
            this.fullQuantityDepth = fullQuantityDepth;
 

	
 
            // first, sort reagents by cost.
 
            InitSortedReagents();
 
            this.maxReagents = (uint)Math.Min(costSortedReagents.Count, this.maxReagents);
 

	
 
            totalReagents = (uint)costSortedReagents.Count;
 

	
 
            // Pre-populate recipes list with:
 
            // 1) 1-ingredient recipes @ 10db for all enabled ingredients with a count >= 10
 
            // 2) any previously-generated recipes
 
            PaintRecipe recipe = new PaintRecipe();
 
            recipe.Reactions = reactions;
 
            foreach (Reagent reagent in costSortedReagents)
 
            {
 
                if (!reagent.IsCatalyst && reagent.RecipeMax >= 10)
 
                if (!reagent.IsCatalyst && reagent.RecipeMax >= 10 && reagent.Enabled)
 
                {
 
                    recipe.Clear();
 
                    recipe.AddReagent(reagent.Name, 10);
 
                    AddCheapestRecipe(recipe);
 
                }
 
            }
 

	
 
            while (!searchQueue.IsEmpty)
 
            {
 
                SearchNode node;
 
                searchQueue.TryDequeue(out node);
 
            }
 
            for (uint reagentIdx = 0; reagentIdx < costSortedReagents.Count; ++reagentIdx)
 
            {
 
                if (costSortedReagents[(int)reagentIdx].Enabled)
 
                {
 
                SearchNode initialNode = new SearchNode(costSortedReagents, reagentIdx);
 
                initialNode.MaxQuantity = maxQuantity;
 
                initialNode.MaxReagents = maxReagents;
 
                searchQueue.Enqueue(initialNode);
 
            }
 
            }
 
            
 
            // start worker threads to do the actual work
 

	
 
            ResumeRecipeGeneration();
 
        }
 

	
 
        public void ResumeRecipeGeneration()
 
        {
 
            if (running)
 
            {
 
                // Already running - don't start again
 
                return;
 
            }
 
            running = true;
 
            requestCancel = false;
 

	
 
            //System.Console.WriteLine("Resuming recipe generation: pre-threads={0} reagent count={1} search queue={2}", runningThreads, costSortedReagents.Count, searchQueue.Count);
 
            runningThreads = 0; // presumably!
 

	
 
            int threadCount = Math.Min(costSortedReagents.Count, searchQueue.Count);
 
            if (threadCount == 0)
 
            {
 
                if (Finished != null)
 
                {
0 comments (0 inline, 0 general)