From 04e67074d269255534703581ba212c4a24786893 Mon Sep 17 00:00:00 2001 From: Creeper Lv Date: Tue, 13 Jan 2026 03:33:49 +1100 Subject: [PATCH] Finished Project Editor. Builder now supports parallel building. --- Progrart.Cmd/Program.cs | 30 ++++++---- Progrart.Core/JSExecution/ExecutionEngine.cs | 10 +++- Progrart.Core/JSExecution/ProgrartExecutor.cs | 2 +- Progrart.Core/PrimitiveDrawingCore.cs | 1 - Progrart.Core/ProjectSystem/Builder.cs | 35 ++++++++++-- .../Storage/ClassicStorageProvider.cs | 57 +++++++++++-------- Progrart/App.axaml | 6 ++ Progrart/Controls/ConfigEditor.axaml | 54 +++++++++++------- Progrart/Controls/ConfigEditor.axaml.cs | 37 ++++++++++++ .../Controls/ExecuteArgumentItem.axaml.cs | 2 +- .../Controls/ExecuteArgumentsEditor.axaml.cs | 19 +++++++ Progrart/Controls/TargetEditor.axaml | 47 ++++++++------- Progrart/Controls/TargetEditor.axaml.cs | 26 +++++++-- Progrart/Pages/ProjectEditor.axaml | 3 + Progrart/Pages/ProjectEditor.axaml.cs | 49 +++++++++++++++- Progrart/Views/MainView.axaml | 4 +- 16 files changed, 290 insertions(+), 92 deletions(-) diff --git a/Progrart.Cmd/Program.cs b/Progrart.Cmd/Program.cs index fa9dc93..ffb82a2 100644 --- a/Progrart.Cmd/Program.cs +++ b/Progrart.Cmd/Program.cs @@ -1,19 +1,25 @@ using Progrart.Core.ProjectSystem; using Progrart.Core.Storage; +using System.Diagnostics; namespace Progrart.Cmd { internal class Program { - static void Main(string[] args) + static async Task Main(string[] args) { + Trace.Listeners.Add(new TextWriterTraceListener(Console.Out)); string? project_file = null; + bool isParallel = false; string? configuration = null; for (int i = 0; i < args.Length; i++) { string? item = args[i]; switch (item) { + case "-j": + isParallel=true; + break; case "-c": case "--config": case "--configuration": @@ -44,22 +50,24 @@ namespace Progrart.Cmd using var sr = new StreamReader(fs); ClassicStorageProvider provider = new ClassicStorageProvider(di); Builder builder = new Builder(sr, provider); - builder.OnProgressUpdate = (v, m) => + builder.OnProgressUpdate = (max, index) => { - Console.WriteLine($"{v}/{m}"); + Console.WriteLine($"Done {index}/{max}"); }; builder.OnCompleted = () => { Environment.Exit(0); }; - Task.Run(async () => - { - await builder.Build(configuration); - }); - while (true) - { - Thread.Sleep(1000); - } + Console.WriteLine("Start build..."); + //Task.Run(async () => + //{ + //}); + //while (true) + //{ + // Thread.Sleep(1000); + //} + + await builder.Build(configuration, isParallel); } } } diff --git a/Progrart.Core/JSExecution/ExecutionEngine.cs b/Progrart.Core/JSExecution/ExecutionEngine.cs index 26057bd..4cdcf87 100644 --- a/Progrart.Core/JSExecution/ExecutionEngine.cs +++ b/Progrart.Core/JSExecution/ExecutionEngine.cs @@ -44,7 +44,15 @@ namespace Progrart.Core.JSExecution JsObject _obj = new JsObject(Engine); Engine.SetValue("math", _obj); Random r = new Random(); - + Engine.SetValue("def", (string k) => { return Symbols.ContainsKey(k); }); + Engine.SetValue("to_bool", (JsValue v) => { return bool.Parse(v.AsString().ToLower()); }); + Engine.SetValue("to_float", (JsValue v) => { return float.Parse(v.AsString().ToLower()); }); + Engine.SetValue("to_int", (JsValue v) => { return int.Parse(v.AsString().ToLower()); }); + Engine.SetValue("query", (string k, string fallback) => + { + if (Symbols.TryGetValue(k, out var val)) return val; + return fallback; + }); _obj.Set("random", JsObject.FromObject(Engine, new Func(() => { return r.NextDouble(); diff --git a/Progrart.Core/JSExecution/ProgrartExecutor.cs b/Progrart.Core/JSExecution/ProgrartExecutor.cs index 3a7425d..3bc20c4 100644 --- a/Progrart.Core/JSExecution/ProgrartExecutor.cs +++ b/Progrart.Core/JSExecution/ProgrartExecutor.cs @@ -55,7 +55,7 @@ namespace Progrart.Core.JSExecution engine.Engine.SetValue("visual_root", visual_root); engine.Engine.SetValue("line", line); engine.Engine.SetValue("rectangle", rectangle); - engine.Engine.SetValue("rectangle", rectangle); + engine.Engine.SetValue("roundrect", roundrect); engine.Engine.SetValue("oval", oval); engine.Engine.SetValue("triangle", triangle); engine.Engine.SetValue("path", path); diff --git a/Progrart.Core/PrimitiveDrawingCore.cs b/Progrart.Core/PrimitiveDrawingCore.cs index d500ce2..8eb9e51 100644 --- a/Progrart.Core/PrimitiveDrawingCore.cs +++ b/Progrart.Core/PrimitiveDrawingCore.cs @@ -37,7 +37,6 @@ namespace Progrart.Core { Width = W; Height = H; - Trace.WriteLine($"Createing Surface as: {W} x {H}"); info = new SKImageInfo(W, H); surface = SKSurface.Create(info); canvas = surface.Canvas; diff --git a/Progrart.Core/ProjectSystem/Builder.cs b/Progrart.Core/ProjectSystem/Builder.cs index eb8e0be..c340884 100644 --- a/Progrart.Core/ProjectSystem/Builder.cs +++ b/Progrart.Core/ProjectSystem/Builder.cs @@ -1,6 +1,7 @@ using Newtonsoft.Json; using Progrart.Core.JSExecution; using Progrart.Core.Storage; +using System.Diagnostics; namespace Progrart.Core.ProjectSystem { @@ -24,8 +25,6 @@ namespace Progrart.Core.ProjectSystem } public async Task Execute(BuildConfiguration config, BuildItem item) { - //FileInfo src = new FileInfo(Path.Combine(basePath, item.Source)); - //FileInfo tgt = new FileInfo(Path.Combine(basePath, project.OutputDir, item.Target ?? item.Source + ".png")); var args = project.Arguments.Clone(); args.MergeFrom(config.Arguments); args.MergeFrom(item.Arguments); @@ -41,23 +40,47 @@ namespace Progrart.Core.ProjectSystem img.DrawingCore.ToData().SaveTo(img_stream); img_stream.Flush(); } - public async Task Build(string targetConfig) + public async Task Build(string targetConfig, bool isParallel = false) { foreach (var config in project.Configurations) { + Console.WriteLine(config.Name); if (config.Name == targetConfig) { int index = 0; + List tasks = new List(); foreach (var item in config.Items) { - await Execute(config, item); - index++; - OnProgressUpdate?.Invoke(config.Items.Count, index); + if (!isParallel) + { + + await Execute(config, item); + index++; + OnProgressUpdate?.Invoke(config.Items.Count, index); + } + else + { + + var t = Task.Run(async () => + { + index++; + int i = index; + await Execute(config, item); + OnProgressUpdate?.Invoke(config.Items.Count, i); + }); + tasks.Add(t); + } + + } + if (isParallel) + { + await Task.WhenAll(tasks); } OnCompleted?.Invoke(); return; } } + throw new Exception($"Configuration \"{targetConfig}\" not found!"); } } } diff --git a/Progrart.Core/Storage/ClassicStorageProvider.cs b/Progrart.Core/Storage/ClassicStorageProvider.cs index 8e99398..427900f 100644 --- a/Progrart.Core/Storage/ClassicStorageProvider.cs +++ b/Progrart.Core/Storage/ClassicStorageProvider.cs @@ -1,36 +1,43 @@ namespace Progrart.Core.Storage { - public class ClassicStorageProvider : IStorageProvider - { - public DirectoryInfo BaseDirectory; + public class ClassicStorageProvider : IStorageProvider + { + public DirectoryInfo BaseDirectory; - public ClassicStorageProvider(DirectoryInfo baseDirectory) - { - BaseDirectory = baseDirectory; - } + public ClassicStorageProvider(DirectoryInfo baseDirectory) + { + BaseDirectory = baseDirectory; + } - public async Task TryOpenRead(string path) - { - try - { + public async Task TryOpenRead(string path) + { + try + { return File.OpenRead(Path.Combine(BaseDirectory.FullName, path)); } - catch (Exception) - { - return null; - } - } - - public async Task TryOpenWrite(string path) - { - try - { - return File.OpenWrite(Path.Combine(BaseDirectory.FullName, path)); - } - catch (Exception) + catch (Exception) { return null; } } - } + + public async Task TryOpenWrite(string path) + { + try + { + FileInfo fi = new FileInfo(Path.Combine(BaseDirectory.FullName, path)); + var di = fi.Directory; + if (di is not null) + { + if (!di.Exists) + di.Create(); + } + return File.OpenWrite(Path.Combine(BaseDirectory.FullName, path)); + } + catch (Exception) + { + return null; + } + } + } } diff --git a/Progrart/App.axaml b/Progrart/App.axaml index 1a058f4..6dde832 100644 --- a/Progrart/App.axaml +++ b/Progrart/App.axaml @@ -306,5 +306,11 @@ + \ No newline at end of file diff --git a/Progrart/Controls/ConfigEditor.axaml b/Progrart/Controls/ConfigEditor.axaml index 365b2c3..272030b 100644 --- a/Progrart/Controls/ConfigEditor.axaml +++ b/Progrart/Controls/ConfigEditor.axaml @@ -6,31 +6,47 @@ mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Progrart.Controls.ConfigEditor" Margin="5"> - - - - - - - - - - - Name - - Output - - - - Targets - + + + + + + + + + + diff --git a/Progrart/Controls/ConfigEditor.axaml.cs b/Progrart/Controls/ConfigEditor.axaml.cs index d6fa1cd..794c08c 100644 --- a/Progrart/Controls/ConfigEditor.axaml.cs +++ b/Progrart/Controls/ConfigEditor.axaml.cs @@ -1,5 +1,6 @@ using Avalonia.Controls; using AvaloniaEdit.Editing; +using Progrart.Core.ProjectSystem; namespace Progrart.Controls; @@ -12,5 +13,41 @@ public partial class ConfigEditor : UserControl { TargetHolder.Children.Add(new TargetEditor()); }; + RemoveButton.Click += (_, _) => + { + if (Parent is StackPanel panel) + { + panel.Children.Remove(this); + } + }; + } + public void LoadConfig(BuildConfiguration config) + { + Arguments.LoadArguments(config.Arguments); + NameBox.Text = config.Name; + OutputDirBox.Text = config.OutputDir; + foreach (var item in config.Items) + { + TargetHolder.Children.Add(new TargetEditor(item)); + } + } + public BuildConfiguration ObtainConfiguration() + { + BuildConfiguration configuration = new BuildConfiguration(); + configuration.OutputDir = OutputDirBox.Text; + configuration.Name= NameBox.Text; + configuration.Arguments = Arguments.ObtainArguments(); + foreach (var item in TargetHolder.Children) + { + if (item is TargetEditor editor) + { + configuration.Items.Add(editor.GetItem()); + } + } + return configuration; + } + private void NameButton_IsCheckedChanged(object? sender, Avalonia.Interactivity.RoutedEventArgs e) + { + ConfigContent.IsVisible = NameButton.IsChecked ?? false; } } \ No newline at end of file diff --git a/Progrart/Controls/ExecuteArgumentItem.axaml.cs b/Progrart/Controls/ExecuteArgumentItem.axaml.cs index 6931001..1ed017a 100644 --- a/Progrart/Controls/ExecuteArgumentItem.axaml.cs +++ b/Progrart/Controls/ExecuteArgumentItem.axaml.cs @@ -27,5 +27,5 @@ public partial class ExecuteArgumentItem : UserControl } }; } - public (string, string) GetItme() => (KeyBox.Text ?? "", ValueBox.Text ?? ""); + public (string, string) GetItem() => (KeyBox.Text ?? "", ValueBox.Text ?? ""); } \ No newline at end of file diff --git a/Progrart/Controls/ExecuteArgumentsEditor.axaml.cs b/Progrart/Controls/ExecuteArgumentsEditor.axaml.cs index 9c5b98d..71c18d6 100644 --- a/Progrart/Controls/ExecuteArgumentsEditor.axaml.cs +++ b/Progrart/Controls/ExecuteArgumentsEditor.axaml.cs @@ -22,4 +22,23 @@ public partial class ExecuteArgumentsEditor : UserControl ItemHolder.Children.Add(new ExecuteArgumentItem(item.Key, item.Value)); } } + public void Clear() + { + ItemHolder.Children.Clear(); + } + public ExecuteArguments ObtainArguments() + { + ExecuteArguments args = new ExecuteArguments(); + + foreach (var item in ItemHolder.Children) + { + if (item is ExecuteArgumentItem eaItem) + { + var (key, value) = eaItem.GetItem(); + args.data[key] = value; + } + } + + return args; + } } \ No newline at end of file diff --git a/Progrart/Controls/TargetEditor.axaml b/Progrart/Controls/TargetEditor.axaml index 9f1e960..d6ff4f1 100644 --- a/Progrart/Controls/TargetEditor.axaml +++ b/Progrart/Controls/TargetEditor.axaml @@ -5,23 +5,32 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Progrart.TargetEditor"> - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + Source + Output Name: + + + + + + +