# HG changeset patch # User Jason Maltzen # Date 2015-12-26 03:04:25 # Node ID 71732f30532885426e5e36f1216765f2132e9100 # Parent 501aa95c46d731f22c066c31472202c866ead46b 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. diff --git a/DesertPaintLab.csproj b/DesertPaintLab.csproj --- a/DesertPaintLab.csproj +++ b/DesertPaintLab.csproj @@ -72,7 +72,9 @@ - + + PreserveNewest + @@ -95,4 +97,16 @@ + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + \ No newline at end of file diff --git a/PaintRecipe.cs b/PaintRecipe.cs --- a/PaintRecipe.cs +++ b/PaintRecipe.cs @@ -44,6 +44,17 @@ 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 recipe = new List(); @@ -68,7 +79,24 @@ namespace DesertPaintLab } 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); } } diff --git a/PlayerProfile.cs b/PlayerProfile.cs --- a/PlayerProfile.cs +++ b/PlayerProfile.cs @@ -59,6 +59,11 @@ namespace DesertPaintLab 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(); + foreach (PaintColor color in Palette.Colors) + { + this.recipes.Add(color.Name, new PaintRecipe()); + } } public string Directory @@ -88,6 +93,21 @@ namespace DesertPaintLab 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() { @@ -318,12 +338,16 @@ namespace DesertPaintLab public void LoadRecipes() { - this.recipes = new SortedDictionary(); + 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)) { @@ -334,12 +358,11 @@ 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; } @@ -350,13 +373,13 @@ namespace DesertPaintLab { 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); } } } @@ -403,7 +426,7 @@ namespace DesertPaintLab { foreach (PaintRecipe.RecipeIngredient ingredient in recipe.Ingredients) { - colorLine += " " + ingredient.name + " " + ingredient.quantity.ToString(); + colorLine += " " + ingredient.ToString(); } } else @@ -430,7 +453,7 @@ namespace DesertPaintLab public void SetRecipe(PaintRecipe recipe) { string colorName = Palette.FindNearest(recipe.ReactedColor); - recipes[colorName] = recipe; + recipes[colorName].CopyFrom(recipe); } } } diff --git a/RecipeGenerator.cs b/RecipeGenerator.cs --- a/RecipeGenerator.cs +++ b/RecipeGenerator.cs @@ -60,16 +60,25 @@ namespace DesertPaintLab protected class SearchNode { //int initialReagentCount; - List reagents; - public List Reagents + uint[] reagents; + public uint[] Reagents { get { return reagents; } } + uint INVALID_REAGENT; + int nextReagentPos; + public int ReagentCount + { + get + { + return nextReagentPos; + } + } - HashSet reagentInUse = new HashSet(); + bool[] reagentInUse; List costSortedReagents; PaintRecipe testRecipe = null; public PaintRecipe TestRecipe @@ -113,16 +122,38 @@ namespace DesertPaintLab } } - public SearchNode(List costSortedReagents, List reagents) + public SearchNode(List costSortedReagents, uint[] reagents) { this.costSortedReagents = new List(costSortedReagents); - this.reagents = new List(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; } @@ -130,8 +161,19 @@ namespace DesertPaintLab public SearchNode(List costSortedReagents, uint startReagent) { this.costSortedReagents = new List(costSortedReagents); - this.reagents = new List(); - 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; @@ -140,8 +182,19 @@ namespace DesertPaintLab public SearchNode(List costSortedReagents) { this.costSortedReagents = costSortedReagents; - this.reagents = new List(); - 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; @@ -156,26 +209,27 @@ namespace DesertPaintLab { 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; @@ -191,11 +245,11 @@ 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; } } @@ -205,16 +259,16 @@ 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; @@ -233,9 +287,9 @@ 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); @@ -266,12 +320,12 @@ namespace DesertPaintLab { 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 costSortedReagents; // new on construct: PaintRecipe testRecipe = null; @@ -296,7 +350,6 @@ namespace DesertPaintLab bool success = true; Match match; - int reagentIdx = 0; while ((line = reader.ReadLine()) != null) { if (line.Equals("---EndNode---")) @@ -310,10 +363,13 @@ namespace DesertPaintLab { case "Reagents": { - int reagentCount = int.Parse(match.Groups[2].Value); - reagents = new List(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": @@ -324,12 +380,13 @@ 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 { @@ -425,6 +482,11 @@ 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 Recipes @@ -459,16 +521,16 @@ namespace DesertPaintLab } } - public void InitRecipes(SortedDictionary recipes) + public void InitRecipes(SortedDictionary 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); } } @@ -508,12 +570,13 @@ 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); } @@ -762,9 +825,8 @@ 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; @@ -782,9 +844,8 @@ namespace DesertPaintLab { 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); @@ -794,9 +855,9 @@ 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); @@ -816,8 +877,6 @@ namespace DesertPaintLab // Console.WriteLine(msg); // } //} - - return discarded; } private bool Iterate(SearchNode node) @@ -845,26 +904,26 @@ namespace DesertPaintLab { 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; @@ -897,20 +956,11 @@ namespace DesertPaintLab 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; @@ -921,7 +971,7 @@ namespace DesertPaintLab } //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; @@ -1010,8 +1060,14 @@ 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; + } } } } diff --git a/RecipeGeneratorWindow.cs b/RecipeGeneratorWindow.cs --- a/RecipeGeneratorWindow.cs +++ b/RecipeGeneratorWindow.cs @@ -22,6 +22,7 @@ using System; using System.Collections.Generic; +using System.Collections.Concurrent; namespace DesertPaintLab { @@ -54,6 +55,12 @@ namespace DesertPaintLab } } + Gtk.ThreadNotify notifyFinished; + Gtk.ThreadNotify notifyProgress; + Gtk.ThreadNotify notifyNewRecipe; + + ConcurrentQueue pendingNewRecipes = new ConcurrentQueue(); + public RecipeGeneratorWindow(PlayerProfile profile) : base(Gtk.WindowType.Toplevel) { this.profile = profile; @@ -84,9 +91,13 @@ namespace DesertPaintLab profile.LoadRecipes(); // init UI - foreach (string key in profile.Recipes.Keys) + foreach (KeyValuePair pair in profile.Recipes) { - colorStore.AppendValues(key); + if (pair.Value.IsValid) + { + string colorName = pair.Key; + colorStore.AppendValues(colorName); + } } canceling = false; @@ -111,9 +122,13 @@ namespace DesertPaintLab 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) @@ -151,7 +166,7 @@ namespace DesertPaintLab 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 @@ -212,50 +227,58 @@ 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; @@ -264,7 +287,7 @@ namespace DesertPaintLab do { string color = (string)colorStore.GetValue(iter, 0); - if (color.Equals(args.Color)) + if (color.Equals(recipeColor)) { exists = true; break; @@ -276,11 +299,11 @@ 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) @@ -288,38 +311,48 @@ namespace DesertPaintLab 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) diff --git a/bin/Debug/colors.txt b/bin/Debug/colors.txt deleted file mode 100644 --- a/bin/Debug/colors.txt +++ /dev/null @@ -1,182 +0,0 @@ -#F0F8FF AliceBlue -#9966CC Amethyst -#FAEBD7 AntiqueWhite -#00FFFF Aqua -#7FFFD4 Aquamarine -#F0FFFF Azure -#FF91AF BakerMillerPink -#E3CF57 Banana -#7C0A02 BarnRed -#8E388E Beet -#F5F5DC Beige -#FFE4C4 Bisque -#010101 Black -#FFEBCD BlanchedAlmond -#FF6700 BlazeOrange -#0000FF Blue -#8A2BE2 BlueViolet -#873260 Boysenberry -#FF007F BrightPink -#A52A2A Brown -#800020 BurgundyRed -#DEB887 BurlyWood -#8A360F BurntSienna -#8A3324 BurntUmber -#5F9EA0 CadetBlue -#FF6103 CadmiumOrange -#FF9912 CadmiumYellow -#E07020 Carrot -#7FFF00 Chartreuse -#D2691E Chocolate -#3D59AB CobaltBlue -#3D9140 CobaltGreen -#FF7F50 Coral -#6495ED CornflowerBlue -#FFF8DC Cornsilk -#DC143C Crimson -#00008B DarkBlue -#008B8B DarkCyan -#B8860B DarkGoldenRod -#006400 DarkGreen -#A9A9A9 DarkGrey -#1A2421 DarkJungleGreen -#BDB76B DarkKhaki -#8B008B DarkMagenta -#556B2F DarkOliveGreen -#FF8C00 DarkOrange -#9932CC DarkOrchid -#8B0000 DarkRed -#E9967A DarkSalmon -#560319 DarkScarlet -#8FBC8F DarkSeaGreen -#3C1414 DarkSienna -#483D8B DarkSlateBlue -#2F4F4F DarkSlateGrey -#00CED1 DarkTurquoise -#9400D3 DarkViolet -#FF1493 DeepPink -#00BFFF DeepSkyBlue -#696969 DimGrey -#1E90FF DodgerBlue -#00009C DukeBlue -#FCE6C9 EggshellWhite -#00C957 EmeraldGreen -#D19275 Feldspar -#B22222 FireBrick -#FFFAF0 FloralWhite -#228B22 ForestGreen -#FF00FF Fuchsia -#DCDCDC Gainsboro -#F8F8FF GhostWhite -#FFD700 Gold -#DAA520 GoldenRod -#008000 Green -#ADFF2F GreenYellow -#808080 Grey -#F0FFF0 HoneyDew -#FF69B4 HotPink -#002395 ImperialBlue -#CD5C5C IndianRed -#4B0082 Indigo -#FFFFF0 Ivory -#F0E68C Khaki -#E6E6FA Lavender -#FFF0F5 LavenderBlush -#7CFC00 LawnGreen -#FFFACD LemonChiffon -#1A1110 Licorice -#ADD8E6 LightBlue -#F08080 LightCoral -#E0FFFF LightCyan -#FAFAD2 LightGoldenRodYellow -#90EE90 LightGreen -#D3D3D3 LightGrey -#FFB6C1 LightPink -#FFA07A LightSalmon -#20B2AA LightSeaGreen -#87CEFA LightSkyBlue -#8470FF LightSlateBlue -#778899 LightSlateGrey -#B0C4DE LightSteelBlue -#FFFFE0 LightYellow -#00FF00 Lime -#32CD32 LimeGreen -#FAF0E6 Linen -#800000 Maroon -#66CDAA MediumAquaMarine -#0000CD MediumBlue -#BA55D3 MediumOrchid -#9370DB MediumPurple -#3CB371 MediumSeaGreen -#7B68EE MediumSlateBlue -#00FA9A MediumSpringGreen -#48D1CC MediumTurquoise -#C71585 MediumVioletRed -#E3A869 Melon -#191970 MidnightBlue -#F5FFFA MintCream -#FFE4E1 MistyRose -#FFE4B5 Moccasin -#FFDEAD NavajoWhite -#000080 Navy -#FDF5E6 OldLace -#808000 Olive -#6B8E23 OliveDrab -#FFA500 Orange -#FF4500 OrangeRed -#DA70D6 Orchid -#002147 OxfordBlue -#EEE8AA PaleGoldenRod -#98FB98 PaleGreen -#AFEEEE PaleTurquoise -#DB7093 PaleVioletRed -#FFEFD5 PapayaWhip -#FFDAB9 PeachPuff -#33A1C9 Peacock -#32127A PersianIndigo -#F77FBE PersianPink -#CD853F Peru -#FFC0CB Pink -#DDA0DD Plum -#B0E0E6 PowderBlue -#003153 PrussianBlue -#800080 Purple -#C76114 RawSienna -#FF0000 Red -#860111 RedDevil -#004040 RichBlack -#BC8F8F RosyBrown -#4169E1 RoyalBlue -#9B111E RubyRed -#8B4513 SaddleBrown -#FA8072 Salmon -#F4A460 SandyBrown -#92000A Sangria -#308014 SapGreen -#2E8B57 SeaGreen -#321414 SealBrown -#FFF5EE SeaShell -#A0522D Sienna -#C0C0C0 Silver -#87CEEB SkyBlue -#6A5ACD SlateBlue -#708090 SlateGrey -#100C08 SmokeyBlack -#FFFAFA Snow -#00FF7F SpringGreen -#4682B4 SteelBlue -#CC3366 SteelPink -#D2B48C Tan -#008080 Teal -#D8BFD8 Thistle -#FF6347 Tomato -#40E0D0 Turquoise -#66023C TyrianPurple -#EE82EE Violet -#D02090 VioletRed -#F5DEB3 Wheat -#FFFFFF White -#F5F5F5 WhiteSmoke -#FFFF00 Yellow -#9ACD32 YellowGreen -#0014A8 Zaffre diff --git a/bin/Debug/ingredients.txt b/bin/Debug/ingredients.txt deleted file mode 100644 --- a/bin/Debug/ingredients.txt +++ /dev/null @@ -1,19 +0,0 @@ -// Desert Paint Lab Ingredients -// Name | Practical Paint Name | RGB values -// These should be kept in the order they show up on the paint bench - -Cabbage Juice | Cabbage | 128, 64, 144 -Carrot | Carrot | 224, 112, 32 -Clay | Clay | 128, 96, 32 -Dead Tongue | DeadTongue | 112, 64, 64 -Toad Skin | ToadSkin | 48, 96, 48 -Earth Light | EarthLight | 128, 240, 224 -Red Sand | RedSand | 144, 16, 24 -Lead | Lead | 80, 80, 96 -Silver Powder | Silver | 16, 16, 32 -Iron | Iron | 96, 48, 32 -Copper | Copper | 64, 192, 192 -Sulfur | Sulfur | catalyst -Potash | Potash | catalyst -Lime | Lime | catalyst -Saltpeter | Saltpeter | catalyst diff --git a/bin/Debug/template/dp_reactions.txt b/bin/Debug/template/dp_reactions.txt deleted file mode 100644 --- a/bin/Debug/template/dp_reactions.txt +++ /dev/null @@ -1,1 +0,0 @@ - \ No newline at end of file diff --git a/bin/Debug/template/ingredients.txt b/bin/Debug/template/ingredients.txt deleted file mode 100644 --- a/bin/Debug/template/ingredients.txt +++ /dev/null @@ -1,21 +0,0 @@ -// Ingredients are in the form: -// Name | RGB values | cost | enabled (Y/N) | bulk/normal | max items per paint (1-20) -// -// It is recommended to only change the cost value -// It is not recommended to set many of the ingredients above 10 per paint - -Cabbage | 128, 64, 144 | 8 | Y | bulk | 10 -Carrot | 224, 112, 32 | 8 | Y | bulk | 10 -Clay | 128, 96, 32 | 10 | Y | bulk | 20 -DeadTongue | 112, 64, 64 | 500 | Y | normal | 4 -ToadSkin | 48, 96, 48 | 500 | Y | normal | 4 -EarthLight | 128, 240, 224 | 10000 | Y | normal | 4 -RedSand | 144, 16, 24 | 4 | Y | bulk | 20 -Lead | 80, 80, 96 | 50 | Y | normal | 6 -Silver | 16, 16, 32 | 50 | Y | normal | 6 -Iron | 96, 48, 32 | 30 | Y | normal | 8 -Copper | 64, 192, 192 | 30 | Y | normal | 8 -Sulfur | catalyst | 15 | Y | normal | 1 -Potash | catalyst | 50 | Y | normal | 1 -Lime | catalyst | 20 | Y | normal | 1 -Saltpeter | catalyst | 10 | Y | normal | 1 diff --git a/bin/Release/colors.txt b/bin/Release/colors.txt deleted file mode 100644 --- a/bin/Release/colors.txt +++ /dev/null @@ -1,182 +0,0 @@ -#F0F8FF AliceBlue -#9966CC Amethyst -#FAEBD7 AntiqueWhite -#00FFFF Aqua -#7FFFD4 Aquamarine -#F0FFFF Azure -#FF91AF BakerMillerPink -#E3CF57 Banana -#7C0A02 BarnRed -#8E388E Beet -#F5F5DC Beige -#FFE4C4 Bisque -#010101 Black -#FFEBCD BlanchedAlmond -#FF6700 BlazeOrange -#0000FF Blue -#8A2BE2 BlueViolet -#873260 Boysenberry -#FF007F BrightPink -#A52A2A Brown -#800020 BurgundyRed -#DEB887 BurlyWood -#8A360F BurntSienna -#8A3324 BurntUmber -#5F9EA0 CadetBlue -#FF6103 CadmiumOrange -#FF9912 CadmiumYellow -#E07020 Carrot -#7FFF00 Chartreuse -#D2691E Chocolate -#3D59AB CobaltBlue -#3D9140 CobaltGreen -#FF7F50 Coral -#6495ED CornflowerBlue -#FFF8DC Cornsilk -#DC143C Crimson -#00008B DarkBlue -#008B8B DarkCyan -#B8860B DarkGoldenRod -#006400 DarkGreen -#A9A9A9 DarkGrey -#1A2421 DarkJungleGreen -#BDB76B DarkKhaki -#8B008B DarkMagenta -#556B2F DarkOliveGreen -#FF8C00 DarkOrange -#9932CC DarkOrchid -#8B0000 DarkRed -#E9967A DarkSalmon -#560319 DarkScarlet -#8FBC8F DarkSeaGreen -#3C1414 DarkSienna -#483D8B DarkSlateBlue -#2F4F4F DarkSlateGrey -#00CED1 DarkTurquoise -#9400D3 DarkViolet -#FF1493 DeepPink -#00BFFF DeepSkyBlue -#696969 DimGrey -#1E90FF DodgerBlue -#00009C DukeBlue -#FCE6C9 EggshellWhite -#00C957 EmeraldGreen -#D19275 Feldspar -#B22222 FireBrick -#FFFAF0 FloralWhite -#228B22 ForestGreen -#FF00FF Fuchsia -#DCDCDC Gainsboro -#F8F8FF GhostWhite -#FFD700 Gold -#DAA520 GoldenRod -#008000 Green -#ADFF2F GreenYellow -#808080 Grey -#F0FFF0 HoneyDew -#FF69B4 HotPink -#002395 ImperialBlue -#CD5C5C IndianRed -#4B0082 Indigo -#FFFFF0 Ivory -#F0E68C Khaki -#E6E6FA Lavender -#FFF0F5 LavenderBlush -#7CFC00 LawnGreen -#FFFACD LemonChiffon -#1A1110 Licorice -#ADD8E6 LightBlue -#F08080 LightCoral -#E0FFFF LightCyan -#FAFAD2 LightGoldenRodYellow -#90EE90 LightGreen -#D3D3D3 LightGrey -#FFB6C1 LightPink -#FFA07A LightSalmon -#20B2AA LightSeaGreen -#87CEFA LightSkyBlue -#8470FF LightSlateBlue -#778899 LightSlateGrey -#B0C4DE LightSteelBlue -#FFFFE0 LightYellow -#00FF00 Lime -#32CD32 LimeGreen -#FAF0E6 Linen -#800000 Maroon -#66CDAA MediumAquaMarine -#0000CD MediumBlue -#BA55D3 MediumOrchid -#9370DB MediumPurple -#3CB371 MediumSeaGreen -#7B68EE MediumSlateBlue -#00FA9A MediumSpringGreen -#48D1CC MediumTurquoise -#C71585 MediumVioletRed -#E3A869 Melon -#191970 MidnightBlue -#F5FFFA MintCream -#FFE4E1 MistyRose -#FFE4B5 Moccasin -#FFDEAD NavajoWhite -#000080 Navy -#FDF5E6 OldLace -#808000 Olive -#6B8E23 OliveDrab -#FFA500 Orange -#FF4500 OrangeRed -#DA70D6 Orchid -#002147 OxfordBlue -#EEE8AA PaleGoldenRod -#98FB98 PaleGreen -#AFEEEE PaleTurquoise -#DB7093 PaleVioletRed -#FFEFD5 PapayaWhip -#FFDAB9 PeachPuff -#33A1C9 Peacock -#32127A PersianIndigo -#F77FBE PersianPink -#CD853F Peru -#FFC0CB Pink -#DDA0DD Plum -#B0E0E6 PowderBlue -#003153 PrussianBlue -#800080 Purple -#C76114 RawSienna -#FF0000 Red -#860111 RedDevil -#004040 RichBlack -#BC8F8F RosyBrown -#4169E1 RoyalBlue -#9B111E RubyRed -#8B4513 SaddleBrown -#FA8072 Salmon -#F4A460 SandyBrown -#92000A Sangria -#308014 SapGreen -#2E8B57 SeaGreen -#321414 SealBrown -#FFF5EE SeaShell -#A0522D Sienna -#C0C0C0 Silver -#87CEEB SkyBlue -#6A5ACD SlateBlue -#708090 SlateGrey -#100C08 SmokeyBlack -#FFFAFA Snow -#00FF7F SpringGreen -#4682B4 SteelBlue -#CC3366 SteelPink -#D2B48C Tan -#008080 Teal -#D8BFD8 Thistle -#FF6347 Tomato -#40E0D0 Turquoise -#66023C TyrianPurple -#EE82EE Violet -#D02090 VioletRed -#F5DEB3 Wheat -#FFFFFF White -#F5F5F5 WhiteSmoke -#FFFF00 Yellow -#9ACD32 YellowGreen -#0014A8 Zaffre diff --git a/bin/Release/ingredients.txt b/bin/Release/ingredients.txt deleted file mode 100644 --- a/bin/Release/ingredients.txt +++ /dev/null @@ -1,19 +0,0 @@ -// Desert Paint Lab Ingredients -// Name | Practical Paint Name | RGB values -// These should be kept in the order they show up on the paint bench - -Cabbage Juice | Cabbage | 128, 64, 144 -Carrot | Carrot | 224, 112, 32 -Clay | Clay | 128, 96, 32 -Dead Tongue | DeadTongue | 112, 64, 64 -Toad Skin | ToadSkin | 48, 96, 48 -Earth Light | EarthLight | 128, 240, 224 -Red Sand | RedSand | 144, 16, 24 -Lead | Lead | 80, 80, 96 -Silver Powder | Silver | 16, 16, 32 -Iron | Iron | 96, 48, 32 -Copper | Copper | 64, 192, 192 -Sulfur | Sulfur | catalyst -Potash | Potash | catalyst -Lime | Lime | catalyst -Saltpeter | Saltpeter | catalyst diff --git a/bin/Release/template/dp_reactions.txt b/bin/Release/template/dp_reactions.txt deleted file mode 100644 --- a/bin/Release/template/dp_reactions.txt +++ /dev/null @@ -1,1 +0,0 @@ - \ No newline at end of file diff --git a/bin/Release/template/ingredients.txt b/bin/Release/template/ingredients.txt deleted file mode 100644 --- a/bin/Release/template/ingredients.txt +++ /dev/null @@ -1,21 +0,0 @@ -// Ingredients are in the form: -// Name | RGB values | cost | enabled (Y/N) | bulk/normal | max items per paint (1-20) -// -// It is recommended to only change the cost value -// It is not recommended to set many of the ingredients above 10 per paint - -Cabbage | 128, 64, 144 | 8 | Y | bulk | 10 -Carrot | 224, 112, 32 | 8 | Y | bulk | 10 -Clay | 128, 96, 32 | 10 | Y | bulk | 20 -DeadTongue | 112, 64, 64 | 500 | Y | normal | 4 -ToadSkin | 48, 96, 48 | 500 | Y | normal | 4 -EarthLight | 128, 240, 224 | 10000 | Y | normal | 4 -RedSand | 144, 16, 24 | 4 | Y | bulk | 20 -Lead | 80, 80, 96 | 50 | Y | normal | 6 -Silver | 16, 16, 32 | 50 | Y | normal | 6 -Iron | 96, 48, 32 | 30 | Y | normal | 8 -Copper | 64, 192, 192 | 30 | Y | normal | 8 -Sulfur | catalyst | 15 | Y | normal | 1 -Potash | catalyst | 50 | Y | normal | 1 -Lime | catalyst | 20 | Y | normal | 1 -Saltpeter | catalyst | 10 | Y | normal | 1 diff --git a/gtk-gui/gui.stetic b/gtk-gui/gui.stetic --- a/gtk-gui/gui.stetic +++ b/gtk-gui/gui.stetic @@ -6,7 +6,7 @@ - + @@ -1190,7 +1190,7 @@ You can either import an existing Practi - + diff --git a/mac/build-mac-bundle.sh b/mac/build-mac-bundle.sh --- a/mac/build-mac-bundle.sh +++ b/mac/build-mac-bundle.sh @@ -15,9 +15,7 @@ fi /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}