Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workbench fails on large Blueprint files #240

Closed
SilasVt opened this issue Mar 19, 2023 · 7 comments · Fixed by #241
Closed

Workbench fails on large Blueprint files #240

SilasVt opened this issue Mar 19, 2023 · 7 comments · Fixed by #241
Labels
bug Something isn't working
Milestone

Comments

@SilasVt
Copy link

SilasVt commented Mar 19, 2023

When pasting my Main Window Blueprint into the UI field in Workbench devel. (with Code and Style being empty).
It errors out saying TimeoutError. (I need to actually scroll up to see the error message).
As well as the preview section being completely empty.

@sonnyp
Copy link
Contributor

sonnyp commented Mar 19, 2023

For reference

using Gtk 4.0;
using Adw 1;

Adw.Window {

  width-request: 900;
  height-request: 500;
  content:
  Box {
    orientation: vertical;



      Adw.HeaderBar {
                      Gtk.MenuButton{
                
          label: "Config";
          menu-model: file_menu;
          styles ["regular-action"]
          primary: true;
          tooltip-text: _("Save or load premade configurations");
        }
        
        centering-policy: strict;
        title-widget:

        Adw.ViewSwitcherTitle switcher_title {
          stack: stack;
          title: _("TND4core");
        };
        
        [end]
        Gtk.MenuButton{
          child: Image {
            icon-name: "open-menu-symbolic";
          };
          
          menu-model: primary_menu;
          primary: true;
        }
      }

    Adw.ViewStack stack {
      vexpand: true;
      

      Adw.ViewStackPage page1 {
        name: "page1";
        title: _("Motor 1");
        icon-name: "power-profile-balanced-symbolic";
        use-underline: true;
        child:
        
  Gtk.Box {
    orientation: vertical;

    Gtk.Box {
      orientation: horizontal;

      Gtk.Box {
        orientation: vertical;




        Gtk.Box {
          orientation: vertical;

          Gtk.Label {
            styles ["title-4",]
            label: "Display";

          }
          

          
          Gtk.CheckButton m1_view_target_pos_button{
            label: "Target position";
          }
          Gtk.CheckButton m1_view_actual_pos_button{
            label: "Actual position";
          }
          Gtk.CheckButton m1_view_pwm_button{
            label: "PWM";
          }
          Gtk.CheckButton m1_view_pos_limits_button{
            label: "Position limits";
          }
          Gtk.CheckButton m1_view_input_clip_button{
            label: "Input clipping";
          }
        }
        
        Gtk.Box m1_output_modes{
        	orientation: vertical;
        	halign: center;
        
       		 Gtk.Label{ label: "Demo output test basje";
        			styles ["title-4",]
            			halign: center;
            			}
        
            	ComboBoxText m1_demo_mode_selection{
		      items [
		      item1: "No Demo",
		      item2: "Sine",
		      item3: "Triangle",
		      item4: "Square",
		      item5: "Motion",
		      item6: "Manual"
		      ]
		      }
              
        }
        margin-bottom: 10;
      }

      Gtk.Frame {
        Gtk.DrawingArea m1_graph {
          hexpand: true;
          halign: fill;
          vexpand: true;
          valign: fill;
        }
        margin-bottom: 10;
      }

      Gtk.Scale m1_slider{
        orientation: vertical;
        vexpand: true;
        valign: fill;
      }
    }

    Gtk.Box {
      orientation: horizontal;
      hexpand: true;
      halign: fill;
      homogeneous: true;
      
      

        

      //Fcalc Kp Kd Ks block  
      Gtk.Box {
        orientation: vertical;
        halign: center;
      Gtk.Grid {
        halign: center;
        
      Gtk.Label {
          layout { row: 0; column: 0; }
          label: "Fcalc   ";
        }
        Gtk.SpinButton m1_f_calc_value{
          layout { row: 0; column: 1; }
        }
        Gtk.Label {
          layout { row: 1; column: 0; }
          label: "Kp   ";
        }
        Gtk.SpinButton m1_kp_value{
          layout { row: 1; column: 1; }
        }
        Gtk.Label {
          layout { row: 2; column: 0; }
          label: "Kd   ";
        }
        Gtk.SpinButton m1_kd_value{
          layout { row: 2; column: 1; }
        }
        Gtk.Label {
          layout { row: 3; column: 0; }
          label: "Ks   ";
        }
        Gtk.SpinButton m1_ks_value{
          layout { row: 3; column: 1; }
        }
        }
      }


Gtk.Box{
        orientation: vertical;
        halign: center;
      Gtk.Grid {
        halign: center;

        Gtk.Label {
          layout { row: 0; column: 0; }
          label: "Fpwm";
        }
        Gtk.SpinButton m1_pwm_frequency_value{
          layout { row: 0; column: 1; }
        }
        Gtk.Label {
          layout { row: 1; column: 0; }
          label: "PWMmin  ";
        }
        Gtk.SpinButton m1_pwm_min_value{
          layout { row: 1; column: 1; }
        }
        Gtk.Label {
          layout { row: 2; column: 0; }
          label: "PWMmax  ";
        }
        Gtk.SpinButton pm1_wm_max_value{
          layout { row: 2; column: 1; }
        }
        Gtk.Label {
          layout { row: 3; column: 0; }
          label: "PWMRev  ";
        }
        Gtk.SpinButton m1_pwm_reverse_value{
          layout { row: 3; column: 1; }
        }
      }
      }
      
      Gtk.Box {
        orientation: vertical;
        halign: center;
      Gtk.Grid {
        halign: center;

        Gtk.Label {
          layout { row: 0; column: 0; }
          label: "Max position  ";
        }
        Gtk.SpinButton m1_max_position_value{
          layout { row: 0; column: 1; }
        }
        Gtk.Label {
          layout { row: 1; column: 0; }
          label: "Min position  ";
        }
        Gtk.SpinButton m1_min_position_value{
          layout { row: 1; column: 1; }
        }
        Gtk.Label {
          layout { row: 2; column: 0; }
          label: "Clip input  ";
        }
        Gtk.SpinButton m1_clip_input_value{
          layout { row: 2; column: 1; }
        }
        Gtk.Label {
          layout { row: 3; column: 0; }
          label: "Deadzone  ";
        }
        Gtk.SpinButton m1_deadzone_value{
          layout { row: 3; column: 1; }
        }
      }
      } 
      
            Gtk.Box {
        orientation: vertical;
        halign: center;
      Gtk.Grid {
        halign: center;

        Gtk.Label {
          layout { row: 0; column: 0; }
          label: "Max boundary  ";
        }
        Gtk.SpinButton m1_max_boundary_value{
          layout { row: 0; column: 1; }
        }
        Gtk.Label {
          layout { row: 1; column: 0; }
          label: "Min boundary  ";
        }
        Gtk.SpinButton m1_min_boundary_value{
          layout { row: 1; column: 1; }
        }
margin-bottom: 15;
      }
      
      Gtk.Box{
      orientation: vertical;
      halign: center;
      
      
      Gtk.Label m1_copy_label{
      styles ["title-4"]
      label: "Copy to other motor:";
      }
                    
                    
     Gtk.Grid {
    
    
    halign: center;

        

          
          Gtk.Button m1_copy_to_m2_button{
          styles ["destructive-action",]
          tooltip-text: _("Copy these values to other motor. The other values will be overwritten");
          label: "Motor 2";
          layout { row: 0; column:0; }
          margin-end: 10;
          }
                    
          Gtk.Button m1_copy_to_m3_button{
          styles ["destructive-action",]
          tooltip-text: _("Copy these values to other motor. The other values will be overwritten");
          label: "Motor 3";
          layout { row: 0; column: 3; }
          }
          
        }
      }
     }
      
      
      margin-bottom: 16;

    }
      }; 
       } 

      Adw.ViewStackPage page2 {
        name: "page2";
        title: _("Motor 2");
        icon-name: "power-profile-balanced-symbolic";
        use-underline: true;
        child:
        
  Gtk.Box {
    orientation: vertical;

    Gtk.Box {
      orientation: horizontal;

      Gtk.Box {
        orientation: vertical;




        Gtk.Box {
          orientation: vertical;

          Gtk.Label {
            styles ["title-4",]
            label: "Display";

          }
          

          
          Gtk.CheckButton m2_view_target_pos_button{
            label: "Target position";
          }
          Gtk.CheckButton m2_view_actual_pos_button{
            label: "Actual position";
          }
          Gtk.CheckButton m2_view_pwm_button{
            label: "PWM";
          }
          Gtk.CheckButton m2_view_pos_limits_button{
            label: "Position limits";
          }
          Gtk.CheckButton m2_view_input_clip_button{
            label: "Input clipping";
          }
        }
        
        Gtk.Box m2_output_modes{
        	orientation: vertical;
        	halign: center;
        
       		 Gtk.Label{ label: "Demo output test basje";
        			styles ["title-4",]
            			halign: center;
            			}
        
            	ComboBoxText m2_demo_mode_selection{
		      items [
		      item1: "No Demo",
		      item2: "Sine",
		      item3: "Triangle",
		      item4: "Square",
		      item5: "Motion",
		      item6: "Manual"
		      ]
		      }
              
        }
        margin-bottom: 10;
      }

      Gtk.Frame {
        Gtk.DrawingArea m2_graph {
          hexpand: true;
          halign: fill;
          vexpand: true;
          valign: fill;
        }
        margin-bottom: 10;
      }

      Gtk.Scale m2_slider{
        orientation: vertical;
        vexpand: true;
        valign: fill;
      }
    }

    Gtk.Box {
      orientation: horizontal;
      hexpand: true;
      halign: fill;
      homogeneous: true;
      
      

        

      //Fcalc Kp Kd Ks block  
      Gtk.Box {
        orientation: vertical;
        halign: center;
      Gtk.Grid {
        halign: center;
        
      Gtk.Label {
          layout { row: 0; column: 0; }
          label: "Fcalc   ";
        }
        Gtk.SpinButton m2_f_calc_value{
          layout { row: 0; column: 1; }
        }
        Gtk.Label {
          layout { row: 1; column: 0; }
          label: "Kp   ";
        }
        Gtk.SpinButton m2_kp_value{
          layout { row: 1; column: 1; }
        }
        Gtk.Label {
          layout { row: 2; column: 0; }
          label: "Kd   ";
        }
        Gtk.SpinButton m2_kd_value{
          layout { row: 2; column: 1; }
        }
        Gtk.Label {
          layout { row: 3; column: 0; }
          label: "Ks   ";
        }
        Gtk.SpinButton m2_ks_value{
          layout { row: 3; column: 1; }
        }
        }
      }


Gtk.Box{
        orientation: vertical;
        halign: center;
      Gtk.Grid {
        halign: center;

        Gtk.Label {
          layout { row: 0; column: 0; }
          label: "Fpwm";
        }
        Gtk.SpinButton m2_pwm_frequency_value{
          layout { row: 0; column: 1; }
        }
        Gtk.Label {
          layout { row: 1; column: 0; }
          label: "PWMmin  ";
        }
        Gtk.SpinButton m2_pwm_min_value{
          layout { row: 1; column: 1; }
        }
        Gtk.Label {
          layout { row: 2; column: 0; }
          label: "PWMmax  ";
        }
        Gtk.SpinButton pm2_wm_max_value{
          layout { row: 2; column: 1; }
        }
        Gtk.Label {
          layout { row: 3; column: 0; }
          label: "PWMRev  ";
        }
        Gtk.SpinButton m2_pwm_reverse_value{
          layout { row: 3; column: 1; }
        }
      }
      }
      
      Gtk.Box {
        orientation: vertical;
        halign: center;
      Gtk.Grid {
        halign: center;

        Gtk.Label {
          layout { row: 0; column: 0; }
          label: "Max position  ";
        }
        Gtk.SpinButton m2_max_position_value{
          layout { row: 0; column: 1; }
        }
        Gtk.Label {
          layout { row: 1; column: 0; }
          label: "Min position  ";
        }
        Gtk.SpinButton m2_min_position_value{
          layout { row: 1; column: 1; }
        }
        Gtk.Label {
          layout { row: 2; column: 0; }
          label: "Clip input  ";
        }
        Gtk.SpinButton m2_clip_input_value{
          layout { row: 2; column: 1; }
        }
        Gtk.Label {
          layout { row: 3; column: 0; }
          label: "Deadzone  ";
        }
        Gtk.SpinButton m2_deadzone_value{
          layout { row: 3; column: 1; }
        }
      }
      } 
      
            Gtk.Box {
        orientation: vertical;
        halign: center;
      Gtk.Grid {
        halign: center;

        Gtk.Label {
          layout { row: 0; column: 0; }
          label: "Max boundary  ";
        }
        Gtk.SpinButton m2_max_boundary_value{
          layout { row: 0; column: 1; }
        }
        Gtk.Label {
          layout { row: 1; column: 0; }
          label: "Min boundary  ";
        }
        Gtk.SpinButton m2_min_boundary_value{
          layout { row: 1; column: 1; }
        }
margin-bottom: 15;
      }
      
      Gtk.Box{
      orientation: vertical;
      halign: center;
      
      
      Gtk.Label m2_copyLabel{
      styles ["title-4"]
      label: "Copy to other motor:";
      }
                    
                    
     Gtk.Grid {
    
    
    halign: center;

        

          
          Gtk.Button m2_copy_to_m1_button{
          styles ["destructive-action",]
          tooltip-text: _("Copy these values to other motor. The other values will be overwritten");
          label: "Motor 1";
          layout { row: 0; column:0; }
          margin-end: 10;
          }
                    
          Gtk.Button m2_copy_to_m3_button{
          styles ["destructive-action",]
          tooltip-text: _("Copy these values to other motor. The other values will be overwritten");
          label: "Motor 3";
          layout { row: 0; column: 3; }
          }
          
        }
      }
     }
      
      
      margin-bottom: 16;

    }
      }; 
       } 


       Adw.ViewStackPage page3 {
        name: "page3";
        title: _("Motor 3");
        icon-name: "power-profile-balanced-symbolic";
        use-underline: true;
        child:
        
  Gtk.Box {
    orientation: vertical;

    Gtk.Box {
      orientation: horizontal;

      Gtk.Box {
        orientation: vertical;




        Gtk.Box {
          orientation: vertical;

          Gtk.Label {
            styles ["title-4",]
            label: "Display";

          }
          

          
          Gtk.CheckButton m3_view_target_pos_button{
            label: "Target position";
          }
          Gtk.CheckButton m3_view_actual_pos_button{
            label: "Actual position";
          }
          Gtk.CheckButton m3_view_pwm_button{
            label: "PWM";
          }
          Gtk.CheckButton m3_view_pos_limits_button{
            label: "Position limits";
          }
          Gtk.CheckButton m3_view_input_clip_button{
            label: "Input clipping";
          }
        }
        
        Gtk.Box m3_output_modes{
        	orientation: vertical;
        	halign: center;
        
       		 Gtk.Label{ label: "Demo output test basje";
        			styles ["title-4",]
            			halign: center;
            			}
        
            	ComboBoxText m3_demo_mode_selection{
		      items [
		      item1: "No Demo",
		      item2: "Sine",
		      item3: "Triangle",
		      item4: "Square",
		      item5: "Motion",
		      item6: "Manual"
		      ]
		      }
              
        }
        margin-bottom: 10;
      }

      Gtk.Frame {
        Gtk.DrawingArea m3_graph {
          hexpand: true;
          halign: fill;
          vexpand: true;
          valign: fill;
        }
        margin-bottom: 10;
      }

      Gtk.Scale m3_slider{
        orientation: vertical;
        vexpand: true;
        valign: fill;
      }
    }

    Gtk.Box {
      orientation: horizontal;
      hexpand: true;
      halign: fill;
      homogeneous: true;
      
      

        

      //Fcalc Kp Kd Ks block  
      Gtk.Box {
        orientation: vertical;
        halign: center;
      Gtk.Grid {
        halign: center;
        
      Gtk.Label {
          layout { row: 0; column: 0; }
          label: "Fcalc   ";
        }
        Gtk.SpinButton m3_f_calc_value{
          layout { row: 0; column: 1; }
        }
        Gtk.Label {
          layout { row: 1; column: 0; }
          label: "Kp   ";
        }
        Gtk.SpinButton m3_kp_value{
          layout { row: 1; column: 1; }
        }
        Gtk.Label {
          layout { row: 2; column: 0; }
          label: "Kd   ";
        }
        Gtk.SpinButton m3_kd_value{
          layout { row: 2; column: 1; }
        }
        Gtk.Label {
          layout { row: 3; column: 0; }
          label: "Ks   ";
        }
        Gtk.SpinButton m3_ks_value{
          layout { row: 3; column: 1; }
        }
        }
      }


Gtk.Box{
        orientation: vertical;
        halign: center;
      Gtk.Grid {
        halign: center;

        Gtk.Label {
          layout { row: 0; column: 0; }
          label: "Fpwm";
        }
        Gtk.SpinButton m3_pwm_frequency_value{
          layout { row: 0; column: 1; }
        }
        Gtk.Label {
          layout { row: 1; column: 0; }
          label: "PWMmin  ";
        }
        Gtk.SpinButton m3_pwm_min_value{
          layout { row: 1; column: 1; }
        }
        Gtk.Label {
          layout { row: 2; column: 0; }
          label: "PWMmax  ";
        }
        Gtk.SpinButton pm3_wm_max_value{
          layout { row: 2; column: 1; }
        }
        Gtk.Label {
          layout { row: 3; column: 0; }
          label: "PWMRev  ";
        }
        Gtk.SpinButton m3_pwm_reverse_value{
          layout { row: 3; column: 1; }
        }
      }
      }
      
      Gtk.Box {
        orientation: vertical;
        halign: center;
      Gtk.Grid {
        halign: center;

        Gtk.Label {
          layout { row: 0; column: 0; }
          label: "Max position  ";
        }
        Gtk.SpinButton m3_max_position_value{
          layout { row: 0; column: 1; }
        }
        Gtk.Label {
          layout { row: 1; column: 0; }
          label: "Min position  ";
        }
        Gtk.SpinButton m3_min_position_value{
          layout { row: 1; column: 1; }
        }
        Gtk.Label {
          layout { row: 2; column: 0; }
          label: "Clip input  ";
        }
        Gtk.SpinButton m3_clip_input_value{
          layout { row: 2; column: 1; }
        }
        Gtk.Label {
          layout { row: 3; column: 0; }
          label: "Deadzone  ";
        }
        Gtk.SpinButton m3_deadzone_value{
          layout { row: 3; column: 1; }
        }
      }
      } 
      
            Gtk.Box {
        orientation: vertical;
        halign: center;
      Gtk.Grid {
        halign: center;

        Gtk.Label {
          layout { row: 0; column: 0; }
          label: "Max boundary  ";
        }
        Gtk.SpinButton m3_max_boundary_value{
          layout { row: 0; column: 1; }
        }
        Gtk.Label {
          layout { row: 1; column: 0; }
          label: "Min boundary  ";
        }
        Gtk.SpinButton m3_min_boundary_value{
          layout { row: 1; column: 1; }
        }
margin-bottom: 15;
      }
      
      Gtk.Box{
      orientation: vertical;
      halign: center;
      
      
      Gtk.Label m3_copy_label{
      styles ["title-4"]
      label: "Copy to other motor:";
      }
                    
                    
     Gtk.Grid {
    
    
    halign: center;

        

          
          Gtk.Button m3_copy_to_m1_button{
          styles ["destructive-action",]
          tooltip-text: _("Copy these values to other motor. The other values will be overwritten");
          label: "Motor 1";
          layout { row: 0; column:0; }
          margin-end: 10;
          }
                    
          Gtk.Button m3_copy_to_m2_button{
          styles ["destructive-action",]
          tooltip-text: _("Copy these values to other motor. The other values will be overwritten");
          label: "Motor 2";
          layout { row: 0; column: 3; }
          }
          
        }
      }
     }
      
      
      margin-bottom: 16;

    }
      }; 
       } 

      Adw.ViewStackPage page4{
        name: "page4";
        title: _("General");
        icon-name: "preferences-other-symbolic";
        use-underline: true;
        child:
        Box{
          orientation: vertical;
          valign: center;

          Image {
            margin-top: 30;
            icon-name: bind page4.icon-name;
            pixel-size: 128;

          }

          Label {
            margin-top: 24;
            margin-bottom: 24;
            margin-start: 24;
            margin-end: 24;
            label: bind page4.title;
          }
        };
      }
    }

    Adw.ViewSwitcherBar switcher_bar {
      stack: stack;
      reveal: bind switcher_title.title-visible;
    }
      
      Gtk.ActionBar{
        
        Gtk.Statusbar{}
      
       
            [end]
        Gtk.Button send_to_dev_button{
          styles ["suggested-action",]
          
          
          tooltip-text: _("Send to TND4 Device and apply changes");
                child: Adw.ButtonContent {
                
                icon-name: "checkmark-large-symbolic";
                label: _(" Send");
                use-underline: true;
              };
          }
      
        }
  };
  
  
}


menu file_menu {
  section {
    item {
      label: _("Save as");
      //action: "app.saveas";
    }
        
    item {
      label: _("Save");
      //action: "app.save";
    }

  }
  section {
    item {
      label: _("Open");
      //action: "app.open";
    }

  }
}

menu primary_menu {

  section {
    item {
      label: _("Preferences");
      //action: "app.preferences";
    }
    item {
      label: _("Help");
      //action: "app.help";
    }
    item {
      label: _("About TND4core");
      //action: "app.about";
    }
  }
}

@SilasVt
Copy link
Author

SilasVt commented Mar 19, 2023

Also additionally, if you take out any of the pages 1, 2 , or 3. as far as I can tell it does actually work again.

@sonnyp sonnyp changed the title Workbench timeout. Workbench timeout on large Blueprint files Mar 19, 2023
@sonnyp
Copy link
Contributor

sonnyp commented Mar 19, 2023

The error is actually this:

(re.sonny.Workbench.Devel:4): Gjs-WARNING **: 21:14:13.124: JS ERROR: SyntaxError: JSON.parse: unterminated string at line 1 column 81839 of the JSON data @ resource:///re/sonny/Workbench/src/lsp/LSPClient.js:195:19

The timeout is a consequence.

It looks like for some reason - we can't read a lsp message over 81838 bytes
For that particular example we get a Content-Length of 83051 but read_bytes only returns 81838.

If I make the Blueprint larger - I get a higher Content-Length but read_bytes keeps returning a GBytes of 81838 bytes.

I don't know yet if it's a problem with Workbench or Blueprint language server.

https://docs.gtk.org/gio/method.InputStream.read_bytes_async.html

It is not an error if this is smaller than the requested size, as it can happen e.g. near the end of a file, but generally we try to read as many bytes as requested. Zero is returned on end of file (or if count is zero), but never otherwise.

@sonnyp sonnyp added the bug Something isn't working label Mar 19, 2023
@sonnyp
Copy link
Contributor

sonnyp commented Mar 19, 2023

@SilasVt I got it working on my laptop but just to make sure could you check that this branch fixes it for you as well?

#241

Blueprint updates are a bit slow on such a large document. We can work on that at some point.

@SilasVt
Copy link
Author

SilasVt commented Mar 20, 2023

Yes. it is fixed now. I even put in more things for other pages making it almost 1100 lines and its still fine. I don't think speed matters that much, as long as it works at all.

Edit: I played around with it more/kept building my ideas for my app. and sometimes it still comes up with the same error, but with longer timeout. but then seems like it keeps working anyways.

@sonnyp sonnyp added this to the 44 milestone Mar 20, 2023
@sonnyp sonnyp changed the title Workbench timeout on large Blueprint files Workbench fails on large Blueprint files Mar 20, 2023
@sonnyp
Copy link
Contributor

sonnyp commented Mar 20, 2023

The CLI appears to be twice as fast than LSP for this large file.

LSP:

re.sonny.Workbench.Devel-Message: 12:25:11.126: compile: 1230.009 ms

CLI:

sonny@porygon ~/P/Workbench (main)> time blueprint-compiler compile test.blp
...
________________________________________________________
Executed in  630.91 millis    fish           external
   usr time  560.81 millis    0.00 micros  560.81 millis
   sys time   58.74 millis  653.00 micros   58.08 millis

According to quick and lightweight Workbench profiling - the overhead is in blueprint language server

re.sonny.Workbench.Devel-Message: 12:28:05.282: read: 0.273 ms
re.sonny.Workbench.Devel-Message: 12:28:05.282: decode: 0.140 ms
re.sonny.Workbench.Devel-Message: 12:28:05.282: parse: 0.121 ms

@sonnyp
Copy link
Contributor

sonnyp commented Mar 20, 2023

@jameswestman solved it and lsp is now faster than cli for this large blp

https://gitlab.gnome.org/jwestman/blueprint-compiler/-/merge_requests/97

Thanks!

sonnyp added a commit that referenced this issue Mar 20, 2023
James made it 3x times faster on large files
See #240 (comment)
sonnyp added a commit to SoNiC-HeRE/Workbench that referenced this issue Mar 21, 2023
James made it 3x times faster on large files
See workbenchdev#240 (comment)
sonnyp added a commit to AkshayWarrier/Workbench that referenced this issue Mar 21, 2023
James made it 3x times faster on large files
See workbenchdev#240 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants