Changeset - 71732f305328
[Not reviewed]
default
8 7 0
Jason Maltzen (jmaltzen) - 9 years ago 2015-12-26 03:04:25
jason.maltzen@unsanctioned.net
Pre-allocate a bunch of map entries, given that we know there are a fixed set of colors. Use fixed arrays in places where maps/sets were excessive. Switch away from using Gtk.Application.Invoke, which leaks a bunch of memory.
15 files changed with 307 insertions and 601 deletions:
0 comments (0 inline, 0 general)
DesertPaintLab.csproj
Show inline comments
...
 
@@ -71,9 +71,11 @@
 
    <Compile Include="gtk-gui\DesertPaintLab.SimulatorWindow.cs" />
 
    <Compile Include="ScreenCheckDialog.cs" />
 
    <Compile Include="gtk-gui\DesertPaintLab.ScreenCheckDialog.cs" />
 
    <Compile Include="FileUtils.cs" />
 
    <Compile Include="PaintRecipe.cs" />
 
    <Compile Include="PaintRecipe.cs">
 
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 
    </Compile>
 
    <Compile Include="ReactionRecorder.cs" />
 
    <Compile Include="ReactionStatusWindow.cs" />
 
    <Compile Include="gtk-gui\DesertPaintLab.ReactionStatusWindow.cs" />
 
    <Compile Include="RecipeGeneratorWindow.cs" />
...
 
@@ -94,5 +96,17 @@
 
        <GtkDesignInfo generateGettext="False" />
 
      </Properties>
 
    </MonoDevelop>
 
  </ProjectExtensions>
 
  <ItemGroup>
 
    <None Include="data\colors.txt">
 
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 
    </None>
 
    <None Include="data\ingredients.txt">
 
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 
    </None>
 
    <None Include="data\template\dp_reactions.txt">
 
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 
    </None>
 
    <None Include="data\template\ingredients.txt" />
 
  </ItemGroup>
 
</Project>
...
 
\ No newline at end of file
PaintRecipe.cs
Show inline comments
...
 
@@ -43,8 +43,19 @@ namespace DesertPaintLab
 
            {
 
                this.name = name;
 
                this.quantity = quantity;
 
            }
 

	
 
            public RecipeIngredient(RecipeIngredient other)
 
            {
 
                this.name = other.name;
 
                this.quantity = other.quantity;
 
            }
 

	
 
            public override string ToString()
 
            {
 
                return String.Format("{0} {1}", name, quantity);
 
            }
 
        };
 

	
 
        private List<RecipeIngredient> recipe = new List<RecipeIngredient>();
 
        private List<string> reagents = new List<string>();
...
 
@@ -67,9 +78,26 @@ namespace DesertPaintLab
 
                this.reagents.Add(reagentName);
 
            }
 
            foreach (RecipeIngredient copyIngredient in other.recipe)
 
            {
 
                RecipeIngredient ingredient = new RecipeIngredient(copyIngredient.name, copyIngredient.quantity);
 
                RecipeIngredient ingredient = new RecipeIngredient(copyIngredient);
 
                this.recipe.Add(ingredient);
 
            }
 
        }
 

	
 
        public void CopyFrom(PaintRecipe other)
 
        {
 
            this.dirty = true;
 
            this.reactions = other.reactions;
 
            this.reagents.Clear();
 
            foreach (string reagentName in other.reagents)
 
            {
 
                this.reagents.Add(reagentName);
 
            }
 
            this.recipe.Clear();
 
            foreach (RecipeIngredient otherIngredient in other.recipe)
 
            {
 
                RecipeIngredient ingredient = new RecipeIngredient(otherIngredient);
 
                this.recipe.Add(ingredient);
 
            }
 
        }
 

	
PlayerProfile.cs
Show inline comments
...
 
@@ -58,8 +58,13 @@ namespace DesertPaintLab
 
			this.name = name;
 
			this.directory = directory;
 
			this.reactFile = System.IO.Path.Combine(directory, "dp_reactions.txt");
 
            this.reagentFile = System.IO.Path.Combine(directory, "ingredients.txt");
 
            this.recipes = new SortedDictionary<string, PaintRecipe>();
 
            foreach (PaintColor color in Palette.Colors)
 
            {
 
                this.recipes.Add(color.Name, new PaintRecipe());
 
            }
 
		}
 

 
        public string Directory
 
        {
...
 
@@ -87,8 +92,23 @@ namespace DesertPaintLab
 
            get {
 
                return this.recipes;
 
            }
 
        }
 

 
        public int RecipeCount
 
        {
 
            get {
 
                int count = 0;
 
                foreach (PaintRecipe recipe in this.recipes.Values)
 
                {
 
                    if (recipe.IsValid)
 
                    {
 
                        ++count;
 
                    }
 
                }
 
                return count;
 
            }
 
        }
 
		
 
		public void Initialize()
 
		{
 
			// Create new directory.
...
 
@@ -317,14 +337,18 @@ namespace DesertPaintLab
 
		}
 

 
        public void LoadRecipes()
 
        {
 
            this.recipes = new SortedDictionary<string, PaintRecipe>();
 
            foreach (PaintRecipe recipe in this.recipes.Values)
 
            {
 
                recipe.Clear();
 
            }
 
            string recipeFile = System.IO.Path.Combine(directory, "dp_recipes.txt");
 
            string line;
 
            Match match;
 
            bool inRecipe = false;
 
            PaintRecipe recipe = null;
 
            PaintRecipe testRecipe = new PaintRecipe();
 
            testRecipe.Reactions = reactions;
 
            string currentRecipeColor = null;
 
            if (File.Exists(recipeFile))
 
            {
 
                using (StreamReader reader = new StreamReader(recipeFile))
...
 
@@ -333,14 +357,13 @@ namespace DesertPaintLab
 
                    {
 
                        match = recipeHeaderRegex.Match(line); 
 
                        if (match.Success)
 
                        {
 
                            if (recipe != null && currentRecipeColor != null)
 
                            if (testRecipe != null && currentRecipeColor != null)
 
                            {
 
                                recipes.Add(currentRecipeColor, recipe);
 
                                recipes[currentRecipeColor].CopyFrom(testRecipe);
 
                            }
 
                            recipe = new PaintRecipe();
 
                            recipe.Reactions = reactions;
 
                            testRecipe.Clear();
 
                            currentRecipeColor = match.Groups["colorname"].Value;
 
                            inRecipe = true;
 
                        }
 
                        else if (inRecipe)
...
 
@@ -349,15 +372,15 @@ namespace DesertPaintLab
 
                            if (match.Success)
 
                            {
 
                                string ingredient = match.Groups["ingredient"].Value;
 
                                uint quantity = uint.Parse(match.Groups["quantity"].Value);
 
                                recipe.AddReagent(ingredient, quantity);
 
                                testRecipe.AddReagent(ingredient, quantity);
 
                            }
 
                        }
 
                    }
 
                    if (inRecipe)
 
                    {
 
                        recipes.Add(currentRecipeColor, recipe);
 
                        recipes[currentRecipeColor].CopyFrom(testRecipe);
 
                    }
 
                }
 
            }
 
        }
...
 
@@ -402,9 +425,9 @@ namespace DesertPaintLab
 
                    if (recipes.TryGetValue(color.Name, out recipe))
 
                    {
 
                        foreach (PaintRecipe.RecipeIngredient ingredient in recipe.Ingredients)
 
                        {
 
                            colorLine += " " + ingredient.name + " " + ingredient.quantity.ToString();
 
                            colorLine += " " + ingredient.ToString();
 
                        }
 
                    } 
 
                    else
 
                    {
...
 
@@ -429,9 +452,9 @@ namespace DesertPaintLab
 

 
        public void SetRecipe(PaintRecipe recipe)
 
        {
 
            string colorName = Palette.FindNearest(recipe.ReactedColor);
 
            recipes[colorName] = recipe;
 
            recipes[colorName].CopyFrom(recipe);
 
        }
 
	}
 
}
 

RecipeGenerator.cs
Show inline comments
...
 
@@ -59,18 +59,27 @@ namespace DesertPaintLab
 
    {
 
        protected class SearchNode
 
        {
 
            //int initialReagentCount;
 
            List<uint> reagents;
 
            public List<uint> Reagents
 
            uint[] reagents;
 
            public uint[] Reagents
 
            {
 
                get
 
                {
 
                    return reagents;
 
                }
 
            }
 
            uint INVALID_REAGENT;
 
            int nextReagentPos;
 
            public int ReagentCount
 
            {
 
                get
 
                {
 
                    return nextReagentPos;
 
                }
 
            }
 

	
 
            HashSet<uint> reagentInUse = new HashSet<uint>();
 
            bool[] reagentInUse;
 
            List<Reagent> costSortedReagents;
 
            PaintRecipe testRecipe = null;
 
            public PaintRecipe TestRecipe
 
            {
...
 
@@ -112,37 +121,81 @@ namespace DesertPaintLab
 
                    return currentWeights;
 
                }
 
            }
 

	
 
            public SearchNode(List<Reagent> costSortedReagents, List<uint> reagents)
 
            public SearchNode(List<Reagent> costSortedReagents, uint[] reagents)
 
            {
 
                this.costSortedReagents = new List<Reagent>(costSortedReagents);
 
                this.reagents = new List<uint>(reagents);
 
                foreach (uint reagentIdx in reagents)
 
                this.reagents = new uint[costSortedReagents.Count];
 
                INVALID_REAGENT = (uint)costSortedReagents.Count;
 
                nextReagentPos = reagents.Length;
 
                for (int i = this.reagents.Length-1; i >= this.reagents.Length; --i)
 
                {
 
                    reagents[i] = INVALID_REAGENT;
 
                }
 
                for (int i = reagents.Length-1; i >= 0; --i)
 
                {
 
                    reagentInUse.Add(reagentIdx);
 
                    this.reagents[i] = reagents[i];
 
                    if (reagents[i] == INVALID_REAGENT)
 
                    {
 
                        nextReagentPos = i;
 
                    }
 
                }
 
                InitialCount = this.reagents.Count;
 
                MaxReagents = (uint)this.reagents.Count; // better set this later!
 
                reagentInUse = new bool[costSortedReagents.Count];
 
                for (uint reagentIdx = 0; reagentIdx < costSortedReagents.Count; ++reagentIdx)
 
                {
 
                    reagentInUse[reagentIdx] = false;
 
                }
 
                foreach (uint reagentIdx in this.reagents)
 
                {
 
                    if (reagentIdx != INVALID_REAGENT)
 
                    {
 
                        reagentInUse[reagentIdx] = true;
 
                    }
 
                }
 
                InitialCount = nextReagentPos;
 
                MaxReagents = (uint)nextReagentPos; // better set this later!
 
                UsedQuantity = 0;
 
            }
 

	
 
            // top-level search
 
            public SearchNode(List<Reagent> costSortedReagents, uint startReagent)
 
            {
 
                this.costSortedReagents = new List<Reagent>(costSortedReagents);
 
                this.reagents = new List<uint>();
 
                this.reagents.Add(NextFreeReagent(startReagent));
 
                this.reagents = new uint[costSortedReagents.Count];
 
                INVALID_REAGENT = (uint)costSortedReagents.Count;
 
                nextReagentPos = 0;
 
                for (int i = 0; i < reagents.Length; ++i)
 
                {
 
                    this.reagents[i] = INVALID_REAGENT;
 
                }
 
                reagentInUse = new bool[costSortedReagents.Count];
 
                for (uint reagentIdx = 0; reagentIdx < costSortedReagents.Count; ++reagentIdx)
 
                {
 
                    reagentInUse[reagentIdx] = false;
 
                }
 
                this.reagents[nextReagentPos++] = NextFreeReagent(startReagent);
 
                InitialCount = 1; // don't iterate up beyond the start reagent
 
                MaxReagents = 1;
 
                UsedQuantity = 0;
 
            }
 

	
 
            public SearchNode(List<Reagent> costSortedReagents)
 
            {
 
                this.costSortedReagents = costSortedReagents;
 
                this.reagents = new List<uint>();
 
                this.reagents.Add(NextFreeReagent(0));
 
                this.reagents = new uint[costSortedReagents.Count];
 
                INVALID_REAGENT = (uint)costSortedReagents.Count;
 
                nextReagentPos = 0;
 
                for (int i = 0; i < reagents.Length; ++i)
 
                {
 
                    this.reagents[i] = INVALID_REAGENT;
 
                }
 
                reagentInUse = new bool[costSortedReagents.Count];
 
                for (uint reagentIdx = 0; reagentIdx < costSortedReagents.Count; ++reagentIdx)
 
                {
 
                    reagentInUse[reagentIdx] = false;
 
                }
 
                this.reagents[nextReagentPos++] = NextFreeReagent(0);
 
                InitialCount = 0;
 
                MaxReagents = 1;
 
                UsedQuantity = 0;
 
            }
...
 
@@ -155,28 +208,29 @@ namespace DesertPaintLab
 
            public uint LastReagent
 
            {
 
                get
 
                {
 
                    return reagents[reagents.Count - 1];
 
                    return reagents[nextReagentPos - 1];
 
                }
 
            }
 

	
 
            public void RemoveLastReagent()
 
            {
 
                uint reagentIdx = reagents[reagents.Count-1];
 
                uint reagentIdx = reagents[nextReagentPos-1];
 
                ReleaseReagent(reagentIdx);
 
                if (costSortedReagents[(int)reagentIdx].IsCatalyst)
 
                {
 
                    --CatalystCount;
 
                }
 
                reagents.RemoveAt(reagents.Count-1);
 
                reagents[nextReagentPos-1] = INVALID_REAGENT;
 
                --nextReagentPos;
 
            }
 

	
 
            public void ReplaceLastReagent(uint reagentIdx)
 
            {
 
                uint oldReagentIdx = reagents[reagents.Count-1];
 
                uint oldReagentIdx = reagents[nextReagentPos-1];
 
                ReleaseReagent(oldReagentIdx);
 
                reagents[reagents.Count-1] = reagentIdx;
 
                reagents[nextReagentPos-1] = reagentIdx;
 
                if (costSortedReagents[(int)oldReagentIdx].IsCatalyst)
 
                {
 
                    --CatalystCount;
 
                }
...
 
@@ -190,13 +244,13 @@ namespace DesertPaintLab
 
            {
 
                uint idx = startIdx;
 
                for (; idx < costSortedReagents.Count; ++idx)
 
                {
 
                    bool inUse = reagentInUse.Contains(idx);
 
                    bool inUse = reagentInUse[idx];
 
                    if (inUse == false)
 
                    {
 
                        //Console.WriteLine("Found free reagent idx {0}", idx);
 
                        reagentInUse.Add(idx);
 
                        reagentInUse[idx] = true;
 
                        return idx;
 
                    }
 
                }
 
                //Console.WriteLine("Failed to find free reagent.");
...
 
@@ -204,18 +258,18 @@ namespace DesertPaintLab
 
            }
 
    
 
            private void ReleaseReagent(uint reagentIdx)
 
            {
 
                reagentInUse.Remove(reagentIdx);
 
                reagentInUse[reagentIdx] = false;
 
            }
 
    
 
            public bool AddNextReagent()
 
            {
 
                bool ok = (reagents.Count < MaxReagents);
 
                bool ok = (nextReagentPos < MaxReagents);
 
                if (ok)
 
                {
 
                    uint nextReagent = NextFreeReagent(0);
 
                    reagents.Add(nextReagent);
 
                    reagents[nextReagentPos++] = nextReagent;
 
                    if (costSortedReagents[(int)nextReagent].IsCatalyst)
 
                    {
 
                        ++CatalystCount;
 
                    }
...
 
@@ -232,11 +286,11 @@ namespace DesertPaintLab
 
                {
 
                    return;
 
                }
 
                UsedQuantity = 0;
 
                uint remainingReagents = ((uint)reagents.Count - CatalystCount);
 
                uint remainingReagents = ((uint)nextReagentPos - CatalystCount);
 
                uint remainingWeight = CurrentTargetQuantity - CatalystCount;
 
                for (int i = 0; i < reagents.Count; ++i)
 
                for (int i = 0; i < nextReagentPos; ++i)
 
                {
 
                    Reagent reagent = Reagent(i);
 
    
 
                    if (reagent.IsCatalyst)
...
 
@@ -265,14 +319,14 @@ namespace DesertPaintLab
 
            public void SaveState(StreamWriter writer)
 
            {
 
                writer.WriteLine("---SearchNode---");
 
                writer.WriteLine("MaxReagents: {0}", MaxReagents);
 
                writer.WriteLine("Reagents: {0}", reagents.Count);
 
                for (int i = 0; i < reagents.Count; ++i)
 
                writer.WriteLine("Reagents: {0}", nextReagentPos);
 
                for (int i = 0; i < nextReagentPos; ++i)
 
                {
 
                    uint idx = reagents[i];
 
                    uint weight = currentWeights[i];
 
                    writer.WriteLine("Reagent: {0},{1},{2}", idx, reagentInUse.Contains(idx) ? 1 : 0, weight);
 
                    writer.WriteLine("Reagent: {0},{1},{2}", idx, reagentInUse[idx] ? 1 : 0, weight);
 
                }
 
                // pulled from parent: List<Reagent> costSortedReagents;
 
                // new on construct: PaintRecipe testRecipe = null;
 
                writer.WriteLine("CurrentTargetQuantity: {0}", CurrentTargetQuantity);
...
 
@@ -295,9 +349,8 @@ namespace DesertPaintLab
 
                }
 

	
 
                bool success = true;
 
                Match match;
 
                int reagentIdx = 0;
 
                while ((line = reader.ReadLine()) != null)
 
                {
 
                    if (line.Equals("---EndNode---"))
 
                    {
...
 
@@ -309,12 +362,15 @@ namespace DesertPaintLab
 
                        switch (match.Groups[1].Value)
 
                        {
 
                            case "Reagents":
 
                                {
 
                                    int reagentCount = int.Parse(match.Groups[2].Value);
 
                                    reagents = new List<uint>(reagentCount);
 
                                    reagentInUse.Clear();
 
                                    reagentIdx = 0;
 
                                    //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":
 
                                {
...
 
@@ -323,14 +379,15 @@ namespace DesertPaintLab
 
                                    {
 
                                        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.Add(reagentId);
 
                                        currentWeights[reagentIdx] = weight;
 
                                        reagents[nextReagentPos] = reagentId;
 
                                        currentWeights[nextReagentPos] = weight;
 
                                        if (isInUse != 0)
 
                                        {
 
                                            reagentInUse.Add(reagentId);
 
                                            reagentInUse[reagentId] = true;
 
                                        }
 
                                        ++nextReagentPos;
 
                                    }
 
                                    else
 
                                    {
 
                                        success = false;
...
 
@@ -424,8 +481,13 @@ namespace DesertPaintLab
 

	
 
        public RecipeGenerator(ReactionSet reactions)
 
        {
 
            this.reactions = reactions;
 
            foreach (PaintColor color in Palette.Colors)
 
            {
 
                recipes.Add(color.Name, new PaintRecipe());
 
                recipeCosts.Add(color.Name, uint.MaxValue);
 
            }
 
        }
 

	
 
        public SortedDictionary<string, PaintRecipe> Recipes
 
        {
...
 
@@ -458,18 +520,18 @@ namespace DesertPaintLab
 
                return (int)reagent1.Cost - (int)reagent2.Cost;
 
            }
 
        }
 

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

	
 
        private void InitSortedReagents()
...
 
@@ -507,14 +569,15 @@ namespace DesertPaintLab
 

	
 
            // 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)
 
                {
 
                    PaintRecipe recipe = new PaintRecipe();
 
                    recipe.Reactions = reactions;
 
                    recipe.Clear();
 
                    recipe.AddReagent(reagent.Name, 10);
 
                    AddCheapestRecipe(recipe);
 
                }
 
            }
...
 
@@ -761,11 +824,10 @@ namespace DesertPaintLab
 
        }
 

	
 
        // Add the cheapest recipe to the recipe list
 
        // returns the discarded recipe from the pair (or null if no original recipe to replace)
 
        private PaintRecipe AddCheapestRecipe(PaintRecipe recipe)
 
        private void AddCheapestRecipe(PaintRecipe recipe)
 
        {
 
            PaintRecipe discarded = recipe;
 
            if (recipe.IsValid)
 
            {
 
                recipe.Reactions = reactions;
 

	
...
 
@@ -781,11 +843,10 @@ namespace DesertPaintLab
 
                    if (recipeCosts.TryGetValue(colorName, out cost))
 
                    {
 
                        if (cost > recipe.Cost)
 
                        {
 
                            discarded = recipes[colorName];
 
                            recipes[colorName].CopyFrom(recipe);
 
                            recipeCosts[colorName] = recipe.Cost;
 
                            recipes[colorName] = recipe;
 
                            if (NewRecipe != null)
 
                            {
 
                                NewRecipeEventArgs args = new NewRecipeEventArgs(colorName, recipe);
 
                                NewRecipe(this, args);
...
 
@@ -793,11 +854,11 @@ namespace DesertPaintLab
 
                        }
 
                    }
 
                    else
 
                    {
 
                        discarded = null;
 
                        // This would be an error!
 
                        recipeCosts.Add(colorName, recipe.Cost);
 
                        recipes.Add(colorName, recipe);
 
                        recipes.Add(colorName, new PaintRecipe(recipe));
 
                        if (NewRecipe != null)
 
                        {
 
                            NewRecipeEventArgs args = new NewRecipeEventArgs(colorName, recipe);
 
                            NewRecipe(this, args);
...
 
@@ -815,10 +876,8 @@ namespace DesertPaintLab
 
            //    lock (workerLock) {
 
            //        Console.WriteLine(msg);
 
            //    }
 
            //}
 
            
 
            return discarded;
 
        }
 

	
 
        private bool Iterate(SearchNode node)
 
        {
...
 
@@ -844,28 +903,28 @@ namespace DesertPaintLab
 
            do
 
            {
 
                if (!node.AddNextReagent())
 
                {
 
                    while ((node.Reagents.Count > node.InitialCount) && (node.LastReagent == (totalReagents-1)))
 
                    while ((node.ReagentCount > node.InitialCount) && (node.LastReagent == (totalReagents-1)))
 
                    {
 
                        node.RemoveLastReagent();
 
                    }
 
                    if (node.Reagents.Count == node.InitialCount)
 
                    if (node.ReagentCount == node.InitialCount)
 
                    {
 
                        // done
 
                        return false;
 
                    }
 
                    uint nextReagent = node.NextFreeReagent(node.LastReagent);
 
                    while ((node.Reagents.Count > node.InitialCount) && (nextReagent >= totalReagents))
 
                    while ((node.ReagentCount > node.InitialCount) && (nextReagent >= totalReagents))
 
                    {
 
                        // No more reagents to try at this level
 
                        node.RemoveLastReagent();
 
                        if (node.Reagents.Count > node.InitialCount)
 
                        if (node.ReagentCount > node.InitialCount)
 
                        {
 
                            nextReagent = node.NextFreeReagent(node.LastReagent);
 
                        }
 
                    }
 
                    if (node.Reagents.Count == node.InitialCount)
 
                    if (node.ReagentCount == node.InitialCount)
 
                    {
 
                        // done
 
                        return false;
 
                    }
...
 
@@ -896,22 +955,13 @@ namespace DesertPaintLab
 
                node.TestRecipe = new PaintRecipe();
 
                node.TestRecipe.Reactions = reactions;
 
            }
 
            node.TestRecipe.Clear();
 
            for (int i = 0; i < node.Reagents.Count; ++i)
 
            for (int i = 0; i < node.ReagentCount; ++i)
 
            {
 
                node.TestRecipe.AddReagent(node.Reagent(i).Name, node.CurrentWeights[i]);
 
            }
 
            PaintRecipe replacement = AddCheapestRecipe(node.TestRecipe);
 
            if (replacement == null)
 
            {
 
                node.TestRecipe = new PaintRecipe();
 
                node.TestRecipe.Reactions = reactions;
 
            }
 
            else
 
            {
 
                node.TestRecipe = replacement;
 
            }
 
            AddCheapestRecipe(node.TestRecipe);
 
            
 
            // check for the next recipe
 
            uint remainingWeight = node.CurrentTargetQuantity - node.CatalystCount;
 
            if (remainingWeight < 10)
...
 
@@ -920,9 +970,9 @@ namespace DesertPaintLab
 
                return false;
 
            }
 
            //uint remainingReagents = (uint)node.Reagents.Count - node.CatalystCount;
 

	
 
            uint depth = (uint)node.Reagents.Count;
 
            uint depth = (uint)node.ReagentCount;
 
            uint weightToConsume = 0;
 
            uint spaceBelow = 0;
 
            int reagentsBelow = 0;
 
            for (int i = (int)depth-1 ; i >= 0; --i)
...
 
@@ -1009,10 +1059,16 @@ namespace DesertPaintLab
 
        }
 

	
 
        public void Reset()
 
        {
 
            recipes.Clear();
 
            recipeCosts.Clear();
 
            foreach (PaintRecipe recipe in recipes.Values)
 
            {
 
                recipe.Clear();
 
            }
 
            foreach (string key in recipeCosts.Keys)
 
            {
 
                recipeCosts[key] = uint.MaxValue;
 
            }
 
        }
 
    }
 
}
 

	
RecipeGeneratorWindow.cs
Show inline comments
...
 
@@ -21,8 +21,9 @@
 
*/
 

	
 
using System;
 
using System.Collections.Generic;
 
using System.Collections.Concurrent;
 

	
 
namespace DesertPaintLab
 
{
 
    public partial class RecipeGeneratorWindow : Gtk.Window
...
 
@@ -53,8 +54,14 @@ namespace DesertPaintLab
 
                return colorStore;   
 
            }
 
        }
 

	
 
        Gtk.ThreadNotify notifyFinished;
 
        Gtk.ThreadNotify notifyProgress;
 
        Gtk.ThreadNotify notifyNewRecipe;
 

	
 
        ConcurrentQueue<PaintRecipe> pendingNewRecipes = new ConcurrentQueue<PaintRecipe>();
 

	
 
        public RecipeGeneratorWindow(PlayerProfile profile) : base(Gtk.WindowType.Toplevel)
 
        {
 
            this.profile = profile;
 
            this.Build();
...
 
@@ -83,11 +90,15 @@ namespace DesertPaintLab
 

	
 
            profile.LoadRecipes();
 

	
 
            // init UI
 
            foreach (string key in profile.Recipes.Keys)
 
            foreach (KeyValuePair<string, PaintRecipe> pair in profile.Recipes)
 
            {
 
                colorStore.AppendValues(key);
 
                if (pair.Value.IsValid)
 
                {
 
                    string colorName = pair.Key;
 
                    colorStore.AppendValues(colorName);
 
                }
 
            }
 

	
 
            canceling = false;
 
            running = false;
...
 
@@ -110,11 +121,15 @@ namespace DesertPaintLab
 
                    stopResumeButton.Label = "Resume";
 
                    stopResumeButton.Sensitive = true;
 
                }
 
            }
 
            countLabel.Text = String.Format("{0} / {1}", generator.Recipes.Count, Palette.Count);
 
            countLabel.Text = String.Format("{0} / {1}", profile.RecipeCount, Palette.Count);
 

	
 
            Destroyed += OnDestroyed;
 

	
 
            notifyFinished = new Gtk.ThreadNotify(new Gtk.ReadyEvent(HandleFinished));
 
            notifyProgress = new Gtk.ThreadNotify(new Gtk.ReadyEvent(HandleProgress));
 
            notifyNewRecipe = new Gtk.ThreadNotify(new Gtk.ReadyEvent(HandleNewRecipe));
 
        }
 

	
 
        protected void OnMaxIngredientsChanged(object sender, EventArgs e)
 
        {
...
 
@@ -150,9 +165,9 @@ namespace DesertPaintLab
 
            stopResumeButton.Sensitive = true;
 
            fullQuantitySpinButton.Sensitive = false;
 
            fullQuantityDepthSpinButton.Sensitive = false;
 

	
 
            countLabel.Text = String.Format("{0} / {1}", generator.Recipes.Count, Palette.Count);
 
            countLabel.Text = String.Format("{0} / {1}", profile.RecipeCount, Palette.Count);
 

	
 
            // TODO: hook up event notifications
 
            // - progress
 
            // - complete
...
 
@@ -211,61 +226,69 @@ namespace DesertPaintLab
 
                }
 
            }
 
        }
 

	
 
        protected void OnFinished(object sender, EventArgs args)
 
        private void HandleFinished()
 
        {
 
            Gtk.Application.Invoke(delegate {
 
                generator.Wait();
 
                if (pauseForCheckpoint)
 
            generator.Wait();
 
            if (pauseForCheckpoint)
 
            {
 
                pauseForCheckpoint = false;
 
                generator.SaveState(System.IO.Path.Combine(profile.Directory, STATE_FILE));
 
                generator.ResumeRecipeGeneration();
 
            }
 
            else
 
            {
 
                running = false;
 
                beginButton.Sensitive = true;
 
                ExportToWikiAction.Sensitive = true;
 
                IngredientsAction.Sensitive = true;
 
                stopResumeButton.Sensitive = false;
 
                maxIngredientsSpinButton.Sensitive = true;
 
                maxRecipeSpinButton.Sensitive = true;
 
                fullQuantitySpinButton.Sensitive = true;
 
                fullQuantityDepthSpinButton.Sensitive = true;
 
                //generator = null; // don't. Hang on to generator for resume.
 
                profile.SaveRecipes();
 
                if (canceling)
 
                {
 
                    pauseForCheckpoint = false;
 
                    generator.SaveState(System.IO.Path.Combine(profile.Directory, STATE_FILE));
 
                    generator.ResumeRecipeGeneration();
 
                    stopResumeButton.Label = "Resume";
 
                    stopResumeButton.Sensitive = true;
 
                    beginButton.Label = "Restart";
 
                }
 
                else
 
                {
 
                    running = false;
 
                    beginButton.Sensitive = true;
 
                    ExportToWikiAction.Sensitive = true;
 
                    IngredientsAction.Sensitive = true;
 
                    stopResumeButton.Sensitive = false;
 
                    maxIngredientsSpinButton.Sensitive = true;
 
                    maxRecipeSpinButton.Sensitive = true;
 
                    fullQuantitySpinButton.Sensitive = true;
 
                    fullQuantityDepthSpinButton.Sensitive = true;
 
                    //generator = null; // don't. Hang on to generator for resume.
 
                    profile.SaveRecipes();
 
                    if (canceling)
 
                    {
 
                        generator.SaveState(System.IO.Path.Combine(profile.Directory, STATE_FILE));
 
                        stopResumeButton.Label = "Resume";
 
                        stopResumeButton.Sensitive = true;
 
                        beginButton.Label = "Restart";
 
                    }
 
                    else
 
                    {
 
                        System.IO.File.Delete(System.IO.Path.Combine(profile.Directory, STATE_FILE));
 
                    }
 
                    System.IO.File.Delete(System.IO.Path.Combine(profile.Directory, STATE_FILE));
 
                }
 
            });
 
            }
 
        }
 

	
 
        protected void OnNewRecipe(object sender, NewRecipeEventArgs args)
 
        protected void OnFinished(object sender, EventArgs args)
 
        {
 
            PaintRecipe recipe = new PaintRecipe(args.Recipe); // copy it
 
            Gtk.Application.Invoke(delegate
 
            notifyFinished.WakeupMain();
 
            //Gtk.Application.Invoke(delegate {
 
            //    HandleFinished();
 
            //});
 
        }
 

	
 
        private void HandleNewRecipe()
 
        {
 
            progressBar.Pulse();
 
            
 
            PaintRecipe recipe = null;
 
            if (pendingNewRecipes.TryDequeue(out recipe))
 
            {
 
                progressBar.Pulse();
 
                string recipeColor = Palette.FindNearest(recipe.ReactedColor);
 
                // TODO: Add item to recipe list only if not already listed
 
                bool exists = false;
 
                Gtk.TreeIter iter;
 
                if (colorStore.GetIterFirst(out iter))
 
                {
 
                    do
 
                    {
 
                        string color = (string)colorStore.GetValue(iter, 0);
 
                        if (color.Equals(args.Color))
 
                        if (color.Equals(recipeColor))
 
                        {
 
                            exists = true;
 
                            break;
 
                        }
...
 
@@ -275,52 +298,62 @@ namespace DesertPaintLab
 
                {
 
                    //Console.WriteLine("Add new recipe for {0}", args.Color);
 
                    //    bool isMissingReactions = args.Recipe.CheckMissingReactions(ref missingReactions);
 
                    //    string missingReactionLabel = isMissingReactions ? "X" : "";
 
                    colorStore.AppendValues(args.Color); // , missingReactionLabel);
 
                    countLabel.Text = String.Format("{0} / {1}", generator.Recipes.Count, Palette.Count);
 
                    colorStore.AppendValues(recipeColor); // , missingReactionLabel);
 
                    countLabel.Text = String.Format("{0} / {1}", profile.RecipeCount+1, Palette.Count);
 
                }
 
                profile.SetRecipe(recipe);
 

 
    
 
                long progressTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
 
                long delta = progressTime - lastProfileSave;
 
                if (delta >= RECIPE_SAVE_INTERVAL)
 
                {
 
                    profile.SaveRecipes();
 
                    lastProfileSave = progressTime;
 
                }
 
            });
 
            }
 
        }
 

	
 
        protected void OnNewRecipe(object sender, NewRecipeEventArgs args)
 
        {
 
            PaintRecipe recipe = new PaintRecipe(args.Recipe); // copy it, so the worker thread can release
 
            lock(this) {
 
                pendingNewRecipes.Enqueue(recipe);
 
            }
 
            notifyNewRecipe.WakeupMain();
 
            //Gtk.Application.Invoke(delegate {
 
            //    HandleNewRecipe();
 
            //});
 
        }
 

	
 
        private void HandleProgress()
 
        {
 
            long progressTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
 
            long delta = progressTime - lastProgressUpdate;
 
            if (delta > 30)
 
            {
 
                lastProgressUpdate = progressTime;
 
                progressBar.Pulse();
 
            }
 
            delta = progressTime - lastStatusUpdate;
 
            if (delta > 500)
 
            {
 
                lastStatusUpdate = progressTime;
 
                statusLabel.Text = String.Format("Recipes searched: {0:N00}", generator.RecipeCount);
 
            }
 
            delta = progressTime - lastCheckpoint;
 
            if (delta > CHECKPOINT_INTERVAL)
 
            {
 
                lastCheckpoint = progressTime;
 
                pauseForCheckpoint = true;
 
                generator.Stop();
 
            }
 
        }
 

	
 
        protected void OnProgress(object sender, EventArgs args)
 
        {
 
            Gtk.Application.Invoke(delegate
 
            {
 
                // TODO: based on time rather than count
 
                long progressTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
 
                long delta = progressTime - lastProgressUpdate;
 
                if (delta > 30)
 
                {
 
                    progressBar.Pulse();
 
                    lastProgressUpdate = progressTime;
 
                }
 
                delta = progressTime - lastStatusUpdate;
 
                if (delta > 500)
 
                {
 
                    // Update recipe count label as well
 
                    statusLabel.Text = String.Format("Recipes searched: {0:N00}", generator.RecipeCount);
 
                    lastStatusUpdate = progressTime;
 
                }
 
                //progressBar.Fraction = (double)((generator.RecipeCount / 10000) % 100) / 100.0;
 

	
 
                delta = progressTime - lastCheckpoint;
 
                if (delta > CHECKPOINT_INTERVAL)
 
                {
 
                    pauseForCheckpoint = true;
 
                    lastCheckpoint = progressTime;
 
                    generator.Stop();
 
                }
 
            });
 
            notifyProgress.WakeupMain();
 
        }
 

	
 
        protected void OnColorSelected(object o, EventArgs args)
 
        {
bin/Debug/colors.txt
Show inline comments
 
deleted file
bin/Debug/ingredients.txt
Show inline comments
 
deleted file
bin/Debug/template/dp_reactions.txt
Show inline comments
 
deleted file
bin/Debug/template/ingredients.txt
Show inline comments
 
deleted file
bin/Release/colors.txt
Show inline comments
 
deleted file
bin/Release/ingredients.txt
Show inline comments
 
deleted file
bin/Release/template/dp_reactions.txt
Show inline comments
 
deleted file
bin/Release/template/ingredients.txt
Show inline comments
 
deleted file
gtk-gui/gui.stetic
Show inline comments
...
 
@@ -5,9 +5,9 @@
 
    <target-gtk-version>2.12</target-gtk-version>
 
  </configuration>
 
  <import>
 
    <widget-library name="glade-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
 
    <widget-library name="../bin/Release/DesertPaintLab.exe" internal="true" />
 
    <widget-library name="../bin/Debug/DesertPaintLab.exe" internal="true" />
 
  </import>
 
  <widget class="Gtk.Window" id="MainWindow" design-size="629 265">
 
    <action-group name="Default">
 
      <action id="FileAction">
...
 
@@ -1189,9 +1189,9 @@ You can either import an existing Practi
 
        <property name="BorderWidth">8</property>
 
        <child>
 
          <widget class="Gtk.MenuBar" id="menubar1">
 
            <property name="MemberName" />
 
            <node name="menubar1" type="Menubar">
 
            <node name="__gtksharp_64_Stetic_Editor_ActionMenuBar" type="Menubar">
 
              <node type="Menu" action="ExportAction">
 
                <node type="Menuitem" action="ExportToWikiAction" />
 
              </node>
 
              <node type="Menu" action="SettingsAction">
mac/build-mac-bundle.sh
Show inline comments
...
 
@@ -14,11 +14,9 @@ fi
 
/bin/cp launcher.sh bin/DesertPaintLab.app/Contents/MacOS
 
/bin/chmod 755 bin/DesertPaintLab.app/Contents/MacOS/launcher.sh
 
/bin/cp ../bin/Release/DesertPaintLab.exe bin/DesertPaintLab.app/Contents/MacOS/
 
/bin/mkdir -p bin/DesertPaintLab.app/Contents/Resources
 
/bin/cp ../bin/Release/colors.txt bin/DesertPaintLab.app/Contents/Resources/
 
/bin/cp ../bin/Release/ingredients.txt bin/DesertPaintLab.app/Contents/Resources/
 
/bin/cp -r ../bin/Release/template bin/DesertPaintLab.app/Contents/Resources/template
 
/bin/cp -r ../data bin/DesertPaintLab.app/Contents/Resources/data
 

	
 
/usr/bin/defaults write `pwd`/bin/DesertPaintLab.app/Contents/Info.plist CFBundleShortVersionString ${VERSION}
 
/usr/bin/defaults write `pwd`/bin/DesertPaintLab.app/Contents/Info.plist CFBundleVersion ${VERSION}
 

	
0 comments (0 inline, 0 general)