Changeset - c9ad5ae6640a
[Not reviewed]
default
0 2 0
Jason Maltzen (jmaltzen) - 9 years ago 2016-01-15 17:25:49
jason.maltzen@unsanctioned.net
Add a thread count for paint recipe generation to settings
2 files changed with 9 insertions and 1 deletions:
0 comments (0 inline, 0 general)
RecipeGenerator.cs
Show inline comments
...
 
@@ -41,64 +41,66 @@ namespace DesertPaintLab
 
        }
 

	
 
        public string Color
 
        {
 
            get {
 
                return color;
 
            }
 
        }
 

	
 
        public PaintRecipe Recipe
 
        {
 
            get {
 
                return recipe;
 
            }
 
        }
 
    }
 

	
 
    public class RecipeGenerator
 
    {
 
        public enum SearchType {
 
            DEPTH_FIRST,
 
            BREADTH_FIRST
 
        };
 

	
 
        public SearchType Mode { get; set; }
 

	
 
        public uint MaxQuantity { get; private set; } // maximum number of total ingredients
 
        public uint MaxReagents { get; private set; } // maximum number of reagents to use in the recipe
 
        public uint MinReagents { get; private set; } // minimum number of reagents to use in the recipe
 
        public uint FullQuantityDepth { get; private set; } // at or equal this number of reagents, ignore ingredient settings for max quantity
 
        public uint FullQuantity { get; private set; }  // The max number of a reagent to use at full quantity
 

	
 
        public uint MaxThreads { get; set; }
 

	
 
        ReactionSet reactions;
 
        bool running = false;
 

	
 
        int runningThreads = 0;
 
        
 
        SortedDictionary<string, uint> recipeCosts = new SortedDictionary<string, uint>();
 
        SortedDictionary<string, PaintRecipe> recipes = new SortedDictionary<string, PaintRecipe>();
 

	
 
        uint totalReagents;
 

	
 
        List<Reagent> costSortedReagents = new List<Reagent>();
 

	
 
        ConcurrentQueue<RecipeSearchNode> searchQueue = new ConcurrentQueue<RecipeSearchNode>();
 

	
 
        ulong recipeCount = 0;
 

	
 
        List<Thread> generatorThreads = new List<Thread>();
 
        Object workerLock = new Object();
 

	
 
        bool requestCancel = false;
 

	
 
        StreamWriter log;
 

	
 
        // events
 
        public event EventHandler Finished;
 
        public event EventHandler Progress;
 
        public event EventHandler<NewRecipeEventArgs> NewRecipe;
 

	
 
        public RecipeGenerator(ReactionSet reactions)
 
        {
 
            Mode = SearchType.BREADTH_FIRST;
 
            this.reactions = reactions;
...
 
@@ -241,76 +243,78 @@ namespace DesertPaintLab
 
                    initialNode.MaxReagents = maxReagents;
 
                    searchQueue.Enqueue(initialNode);
 
                }
 
            }
 

	
 
            recipeCount = 0;
 

	
 
            if (log != null)
 
            {
 
                log.WriteLine("Begin recipe generation: MaxQuantity={0} MinReagents={1} MaxReagents={2} FullQuantity={3} FullQuantityDepth={4}", MaxQuantity, MinReagents, MaxReagents, FullQuantity, FullQuantityDepth);
 
            }
 
            
 
            // 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;
 

	
 
            if (log != null)
 
            {
 
                log.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);
 
            int threadCount = Math.Min(Math.Min(costSortedReagents.Count, searchQueue.Count), (int)MaxThreads);
 
            if (threadCount == 0)
 
            {
 
                if (Finished != null)
 
                {
 
                    Finished(this, null);
 
                }
 
            }
 
            generatorThreads.Clear();
 
            System.Console.WriteLine("Starting {0} generator threads.", threadCount);
 
            for (int i = 0; i < threadCount; ++i)
 
            {
 
                Thread thr = new Thread(new ThreadStart(this.Generate));
 
                thr.Priority = ThreadPriority.BelowNormal;
 
                generatorThreads.Add(thr);
 
            }
 
            foreach (Thread thr in generatorThreads)
 
            {
 
                thr.Start();
 
            }
 
        }
 

	
 
        public bool SaveState(string file)
 
        {
 
            if (running)
 
            {
 
                // can't save state while running
 
                return false;
 
            }
 

	
 
            using (StreamWriter writer = new StreamWriter(file, false))
 
            {
 
                writer.WriteLine("MinReagents: {0}", MinReagents);
 
                writer.WriteLine("MaxReagents: {0}", MaxReagents);
 
                writer.WriteLine("FullQuantityDepth: {0}", FullQuantityDepth);
 
                writer.WriteLine("FullQuantity: {0}", FullQuantity);
 
                writer.WriteLine("TotalReagents: {0}", totalReagents);
 
                writer.WriteLine("RecipeCount: {0}", recipeCount);
 
                writer.WriteLine("SearchType: {0}", Mode.ToString());
 
                foreach (KeyValuePair<string, PaintRecipe> pair in recipes)
 
                {
 
                    PaintRecipe recipe = pair.Value;
 
                    string colorName = Palette.FindNearest(recipe.ReactedColor);
 
                    writer.WriteLine("BeginRecipe: {0}", colorName);
 
                    foreach (PaintRecipe.RecipeIngredient ingredient in recipe.Ingredients)
 
                    {
RecipeGeneratorWindow.cs
Show inline comments
...
 
@@ -87,64 +87,68 @@ namespace DesertPaintLab
 

	
 
            recipeList.AppendColumn(recipeColorColumn);
 
            recipeColorColumn.AddAttribute(recipeColumnCell, "text", 0);
 

	
 
            colorStore.Clear();
 

	
 
            colorStore.SetSortColumnId(0, Gtk.SortType.Ascending);
 
            recipeList.Model = RecipeModel;
 

	
 
            recipeList.Selection.Changed += OnColorSelected;
 

	
 
            recipeIngredientsView.AppendColumn("Quantity", new Gtk.CellRendererText(), "text", 0);
 
            recipeIngredientsView.AppendColumn("Ingredient", new Gtk.CellRendererText(), "text", 1);
 
            recipeIngredientsView.Model = new Gtk.ListStore(typeof(string), typeof(string));
 

	
 
            profile.LoadRecipes();
 

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

	
 
            canceling = false;
 
            running = false;
 
            pauseForCheckpoint = false;
 

	
 
            generator = new RecipeGenerator(profile.Reactions);
 
            int threads;
 
            DesertPaintLab.Settings.Get("GeneratorThreads", out threads);
 
            if (threads <= 0) { threads = 15; }
 
            generator.MaxThreads = (uint)threads;
 
            generator.InitRecipes(profile.Recipes);
 

	
 
            generator.Progress += OnProgress;
 
            generator.Finished += OnFinished;
 
            generator.NewRecipe += OnNewRecipe;
 

	
 
            string stateFile = System.IO.Path.Combine(profile.Directory, STATE_FILE);
 
            if (System.IO.File.Exists(stateFile))
 
            {
 
                generator.LoadState(stateFile);
 
                if (generator.CanResume)
 
                {
 
                    beginButton.Label = "Restart";
 
                    stopResumeButton.Label = "Resume";
 
                    stopResumeButton.Sensitive = true;
 

	
 
                    maxRecipeSpinButton.Value = Math.Max(generator.MaxQuantity, 14); //
 
                    fullQuantitySpinButton.Value = generator.FullQuantity; // TODO: read/save profile info
 
                    fullQuantityDepthSpinButton.Value = generator.FullQuantityDepth; // TODO: read/save profile info
 
                    maxIngredientsSpinButton.Value = generator.MaxReagents;
 
                }
 
            }
 
            //generator.Log = System.IO.Path.Combine(profile.Directory, "dp_log.txt");
 
            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));
 

	
 
            // initialize reagent list
0 comments (0 inline, 0 general)