diff --git a/GrasshopperAsyncComponent/Base/GH_AsyncComponent.cs b/GrasshopperAsyncComponent/Base/GH_AsyncComponent.cs index 3eee2bb..444b08c 100644 --- a/GrasshopperAsyncComponent/Base/GH_AsyncComponent.cs +++ b/GrasshopperAsyncComponent/Base/GH_AsyncComponent.cs @@ -20,13 +20,11 @@ namespace GrasshopperAsyncComponent public override GH_Exposure Exposure => GH_Exposure.hidden; - Action ReportError; - - List<(string, GH_RuntimeMessageLevel)> Errors; + //List<(string, GH_RuntimeMessageLevel)> Errors; Action ReportProgress; - ConcurrentDictionary ProgressReports; + public ConcurrentDictionary ProgressReports; Action Done; @@ -36,7 +34,7 @@ namespace GrasshopperAsyncComponent bool SetData = false; - List Workers; + public List Workers; List Tasks; @@ -56,29 +54,7 @@ namespace GrasshopperAsyncComponent { DisplayProgressTimer = new Timer(333) { AutoReset = false }; - DisplayProgressTimer.Elapsed += (s, e) => - { - if (Workers.Count == 0) return; - if (Workers.Count == 1) - { - Message = ProgressReports.Values.Last().ToString("0.00%"); - } - else - { - double total = 0; - foreach (var kvp in ProgressReports) - { - total += kvp.Value; - } - - Message = (total / Workers.Count).ToString("0.00%"); - } - - Rhino.RhinoApp.InvokeOnUiThread((Action)delegate - { - OnDisplayExpired(true); - }); - }; + DisplayProgressTimer.Elapsed += DisplayProgress; ReportProgress = (id, value) => { @@ -86,8 +62,6 @@ namespace GrasshopperAsyncComponent if (!DisplayProgressTimer.Enabled) DisplayProgressTimer.Start(); }; - ReportError = (error, type) => Errors?.Add((error, type)); - Done = () => { State++; @@ -105,7 +79,6 @@ namespace GrasshopperAsyncComponent } }; - Errors = new List<(string, GH_RuntimeMessageLevel)>(); ProgressReports = new ConcurrentDictionary(); Workers = new List(); @@ -113,6 +86,30 @@ namespace GrasshopperAsyncComponent Tasks = new List(); } + public virtual void DisplayProgress(object sender, System.Timers.ElapsedEventArgs e) + { + if (Workers.Count == 0) return; + if (Workers.Count == 1) + { + Message = ProgressReports.Values.Last().ToString("0.00%"); + } + else + { + double total = 0; + foreach (var kvp in ProgressReports) + { + total += kvp.Value; + } + + Message = (total / Workers.Count).ToString("0.00%"); + } + + Rhino.RhinoApp.InvokeOnUiThread((Action)delegate + { + OnDisplayExpired(true); + }); + } + protected override void BeforeSolveInstance() { if (State != 0 && SetData) return; @@ -121,7 +118,6 @@ namespace GrasshopperAsyncComponent CancelationSources.Clear(); Workers.Clear(); - Errors.Clear(); ProgressReports.Clear(); Tasks.Clear(); @@ -175,11 +171,11 @@ namespace GrasshopperAsyncComponent Task CurrentRun; if (TaskCreationOptions != null) { - CurrentRun = new Task(() => CurrentWorker.DoWork(ReportProgress, ReportError, Done), tokenSource.Token, (TaskCreationOptions)TaskCreationOptions); + CurrentRun = new Task(() => CurrentWorker.DoWork(ReportProgress, Done), tokenSource.Token, (TaskCreationOptions)TaskCreationOptions); } else { - CurrentRun = new Task(() => CurrentWorker.DoWork(ReportProgress, ReportError, Done), tokenSource.Token); + CurrentRun = new Task(() => CurrentWorker.DoWork(ReportProgress, Done), tokenSource.Token); } // Add cancelation source to our bag CancelationSources.Add(tokenSource); @@ -199,14 +195,8 @@ namespace GrasshopperAsyncComponent if (State == 0) { - foreach (var (message, type) in Errors) - { - AddRuntimeMessage(type, message); - } - CancelationSources.Clear(); Workers.Clear(); - Errors.Clear(); ProgressReports.Clear(); Tasks.Clear(); diff --git a/GrasshopperAsyncComponent/Base/WorkerInstance.cs b/GrasshopperAsyncComponent/Base/WorkerInstance.cs index 41bf0bb..aec07a6 100644 --- a/GrasshopperAsyncComponent/Base/WorkerInstance.cs +++ b/GrasshopperAsyncComponent/Base/WorkerInstance.cs @@ -14,6 +14,12 @@ namespace GrasshopperAsyncComponent /// public abstract class WorkerInstance { + + /// + /// The parent component. Useful for passing state back to the host component. + /// + public GH_Component Parent { get; set; } + /// /// This token is set by the parent . /// @@ -24,6 +30,11 @@ namespace GrasshopperAsyncComponent /// public string Id { get; set; } + protected WorkerInstance(GH_Component _parent) + { + Parent = _parent; + } + /// /// This is a "factory" method. It should return a fresh instance of this class, but with all the necessary state that you might have passed on directly from your component. /// @@ -35,9 +46,8 @@ namespace GrasshopperAsyncComponent /// Make sure you always check as frequently as you can if is cancelled. For an example, see the . /// /// Call this to report progress up to the parent component. - /// Call this to report errors up to the parent component. /// Call this when everything is done. It will tell the parent component that you're ready to . - public abstract void DoWork(Action ReportProgress, Action ReportError, Action Done); + public abstract void DoWork(Action ReportProgress, Action Done); /// /// Write your data setting logic here. Do not call this function directly from this class. It will be invoked by the parent after you've called `Done` in the function. diff --git a/GrasshopperAsyncComponent/GrasshopperAsyncComponent.csproj b/GrasshopperAsyncComponent/GrasshopperAsyncComponent.csproj index 30e8f2c..9b3b252 100644 --- a/GrasshopperAsyncComponent/GrasshopperAsyncComponent.csproj +++ b/GrasshopperAsyncComponent/GrasshopperAsyncComponent.csproj @@ -78,8 +78,7 @@ --> - Copy "$(TargetPath)" "$(TargetDir)$(ProjectName).gha" -Erase "$(TargetPath)" + Copy "$(TargetPath)" "$(TargetDir)$(ProjectName).gha" en-US diff --git a/GrasshopperAsyncComponent/Properties/AssemblyInfo.cs b/GrasshopperAsyncComponent/Properties/AssemblyInfo.cs index 3764cb5..bc7322f 100644 --- a/GrasshopperAsyncComponent/Properties/AssemblyInfo.cs +++ b/GrasshopperAsyncComponent/Properties/AssemblyInfo.cs @@ -8,7 +8,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyTitle("GrasshopperAsyncComponent")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] +[assembly: AssemblyCompany("Aec systems")] [assembly: AssemblyProduct("GrasshopperAsyncComponent")] [assembly: AssemblyCopyright("Copyright © 2020")] [assembly: AssemblyTrademark("")] diff --git a/GrasshopperAsyncComponent/SampleImplementations/Sample_PrimeCalculatorAsyncComponent.cs b/GrasshopperAsyncComponent/SampleImplementations/Sample_PrimeCalculatorAsyncComponent.cs index 1d91333..4efe02b 100644 --- a/GrasshopperAsyncComponent/SampleImplementations/Sample_PrimeCalculatorAsyncComponent.cs +++ b/GrasshopperAsyncComponent/SampleImplementations/Sample_PrimeCalculatorAsyncComponent.cs @@ -38,7 +38,9 @@ namespace GrasshopperAsyncComponent.SampleImplementations int TheNthPrime { get; set; } = 100; long ThePrime { get; set; } = -1; - public override void DoWork(Action ReportProgress, Action ReportError, Action Done) + public PrimeCalculatorWorker() : base(null) { } + + public override void DoWork(Action ReportProgress, Action Done) { // 👉 Checking for cancellation! if (CancellationToken.IsCancellationRequested) return; diff --git a/GrasshopperAsyncComponent/SampleImplementations/Sample_UslessCyclesComponent.cs b/GrasshopperAsyncComponent/SampleImplementations/Sample_UslessCyclesComponent.cs index f3204fa..0e04ab0 100644 --- a/GrasshopperAsyncComponent/SampleImplementations/Sample_UslessCyclesComponent.cs +++ b/GrasshopperAsyncComponent/SampleImplementations/Sample_UslessCyclesComponent.cs @@ -36,7 +36,9 @@ namespace GrasshopperAsyncComponent.SampleImplementations { int MaxIterations { get; set; } = 100; - public override void DoWork(Action ReportProgress, Action ReportError, Action Done) + public UselessCyclesWorker() : base(null) { } + + public override void DoWork(Action ReportProgress, Action Done) { // Checking for cancellation if (CancellationToken.IsCancellationRequested) return;