Jump to content

ZigZig

uniGUI Subscriber
  • Posts

    352
  • Joined

  • Last visited

  • Days Won

    28

Posts posted by ZigZig

  1. Erich,

     

    This article could interest you : https://www.sencha.com/blog/optimizing-ext-js-4-1-based-applications/

     

    Ex: in uniEvents of TUniPanel, you can set this function :

    function beforeInit(sender)
    {
       sender.xtype = 'container';
    }

    That will make your application faster if you use lot of TUniPanels.

     

    By the way, that was exactly my answer to a previous post you made last year: http://forums.unigui.com/index.php?/topic/3621-how-to-increase-performance-of-runtime-created-components/&do=findComment&comment=19148... ;)

  2. Hi rasaliad,

     

    Each session has its own instance of MainModule, with its own properties: if many users are connected at the same time, each user will get its own Mainmodule in its own session and its own properties (thus its own pointers to server addresses).

    If you use global vars, you could have the same pointer used by concurrent users at the same time: global vars belong to UserModule (which is the same for all sessions).

  3. Maybe Farshad can comment on this and suggest a better way. Might be good idea to have some kind of Client.PaintLocked until all controls are created. I've been missing this for the uniDBGrid as well. Every action leads to a painting of the grid, but again, maybe I'm missing something else here.

     

    Dear Michael,

     

    It seems that you're not considering previous answers...

     

    f you take a look at the topic about optimizing ExtJs (https://www.sencha.com/blog/optimizing-ext-js-4-1-based-applications/) as I suggested to you here, you will find answers to most of your questions.

     

    For example : you can get something like "Client.PaintLocked" by doing this :

    {
        Ext.suspendLayouts();
        // batch of updates
        Ext.resumeLayouts(true);
    }
    

    To avoid waste of time when filling grids, you have this trick :

      UniSession.JSCode(myGrid.JSName+'.store.suspendEvents();');
    
      //do something to myGrid
      
    
      UniSession.JSCode(mmyGrid.JSName+'.store.resumeEvents();');
      UniSession.JSCode(myGrid.JSName+'.view.refresh();'); 

    (see also this topic : http://forums.unigui.com/index.php?/topic/3837-clear-stringgrid/?p=18367)

     

     

    About Panels, you can decrease loading time with this trick :

    function beforeInit(sender)
    {
       sender.xtype = 'container';
    }
    

    (as I suggested here)

     

     

    By the way, Farshad said that you could send a complete test case... and Zilav suggested that you use DBGrid and ClientDataSet with 2 fields being name and value, and utilize afterpost event to modify the needed fields.  

     

    But I feel that you prefer to complain than try the solutions we offer you.

     

     

     

    But creating a handful of controls at runtime is Delphi standard, and if I cannot do it without large time delays or through complicated quirks, then - for me - what's the point of doing it in Delphi at all?

     

     

    Hum... I'm not sure that creating a handful of controls at runtime is Delphi standard... Anyway, a Web application is not a local PC application.  You must think about architecture, server tasks and client tasks, asynchronous communication with Ajax, etc.  Thinking that you can do the same thing with uniGUi (in a Web project) than with VCL (in a local application) is, imho, a huge mistake.  If you want to do so, I suggest you to try Intraweb or WebFMX (http://www.cybelesoft.com/webfmx/) : there you can build your application as a stand-alone executable and share it on the Internet.  But you cannot do that with uniGUI, that's not the purpose of this wonderful framework.

    • Upvote 2
  4. And concerning the design, it is well thought of: I have a grid, populated by an sql statement at runtime (and there can be infinite sql constructions on 90 existing tables of the database...), and beside the grid I dynamically show a vertical record editor. Every field has a title, an edit control and possibly a button. So if the query has 10 fields, that makes at least 20 controls created at runtime. Or would you rather I design an edit form for every possible joined sql statement containing any possible number of fields? ;-)

    Well... If you don't see any other solution than create 100 controls at runtime or design edit forms for every possible joined sql statement, I think that you really need to think about the way you analyze/modelize your application...

    For example: do your 100 fields need, for each one, titles, controls and button created and shown at the start of you application? Couldn't it be possible to show only 1 control and 1 button on the specific field you're mousing over?  In that case, you just need to create 1 button and 1 control, and show it over the field that your mouse is over...

     

    Anyway, I don't think that the problem is about uniGUi performances, but about the way you want to make your application.

     

    This article could interest you : https://www.sencha.com/blog/optimizing-ext-js-4-1-based-applications/.

     

    Ex: in uniEvents of TUniPanel, you can set this function :

    function beforeInit(sender)
    {
       sender.xtype = 'container';
    }

    That will make your application faster if you use lot of TUniPanels.

  5. "Good idea, or am I totally on the wrong theory?"

     

    That was exactly my suggestion (22th Nov 2013)...

    Anyway, I cannot figure why you need to create 100 controls in runtime.  That is not a good practice, far from OOP, MVC and other design patterns.  Doing that with uniGUI is as odd as doing that with standard VCL or FMx forms.

    Maybe you first need to think about the way you analyze/modelize/build your application, before trying to create so many controls...

  6. Hi codeb,

     

    I think I found a nice solution :

     

    BEFORE clearing your uniStringGrid, put this line in your code :

      UniSession.JSCode(myUniStringGrid.JSName+'.store.suspendEvents();');
    AFTER clearing your uniStringGrid, put the lines:
      UniSession.JSCode(myUniStringGrid.JSName+'.store.resumeEvents();');
      UniSession.JSCode(myUniStringGrid.JSName+'.view.refresh();');
     
    By the way, if some of your operations are too slow (ie creating components in runtime), you can do this :
     
    BEFORE your slow operation
    UniSession.JSCode('Ext.suspendLayouts();');
    AFTER your slow operation
    UniSession.JSCode('Ext.resumeLayouts(true);');

    Everything is fully explained here : http://edspencer.net/2013/07/19/sencha-con-2013-ext-js-performance-tips/

     

     

     

    Hope it'll help you.

  7. Hi,

     

    uniStringGrid is not the most optimized component of uniGUI...

    Anyway, you can try this :

    • set uniStringGrid.Visible to false before clearing it (or before adding lines), and set it to True after your process
    • try to set the property "DoubleBuffered" to True before clearing it (or adding lines)
    • try to use methods "BeginUpdate" and "EndUpdate" when you change something in your StringGrid.

    You should notice better performances (but not so good; uniStringGrid is still a crappy component).

     

    You can also try to use uniDBGrid instead of uniStringGrid... performances are better in some cases.

  8. Here is the way to make TUniEdit observable by LiveBindings :

    unit UniObservableEdit;
    
    interface
    
    uses
      System.SysUtils, System.Classes, Vcl.Controls, uniGUIBaseClasses,
      uniGUIClasses, uniEdit,
      WinApi.Messages, WinApi.CommCtrl,
      Data.Bind.Components;
    
    type
      [ObservableMember('Text')]                            { identifies the control value name for TUniObservableEdit }
    
      TUniObservableEdit = class(TUniEdit)
      private
        procedure ObserverToggle(const AObserver: IObserver; const Value: Boolean);
        procedure DoSetRemoteValue(AIndex:Integer;Value:String);override;
      protected
        function CanObserve(const ID: Integer): Boolean; override;                       { declaration is in System.Classes }
        procedure ObserverAdded(const ID: Integer; const Observer: IObserver);  override; { declaration is in System.Classes }
      public
      published
      end;
    
    procedure Register;
    
    implementation
    
    
    function TUniObservableEdit.CanObserve(const ID: Integer): Boolean;
    { Controls which implement observers always override TComponent.CanObserve(const ID: Integer). }
    { This method identifies the type of observers supported by TUniObservableEdit. }
    begin
      case ID of
        TObserverMapping.EditLinkID,      { EditLinkID is the observer that is used for control-to-field links }
        TObserverMapping.ControlValueID:
          Result := True;
      else
        Result := False;
      end;
    end;
    
    { The override for DoSetRemoteValue is where TUniObservableEdit calls the
      observable interfaces to notify LiveBindings components when the user types something.
      This override is sufficient to monitor user input to TUniObservableEdit.
      TLinkObservers.ControlChanged is a utility method that does most of the work. You can
      find the implementation in System.Classes. }
    
    procedure TUniObservableEdit.DoSetRemoteValue(AIndex:Integer;Value:String);
    begin
      inherited;
      TLinkObservers.ControlChanged(Self);
    end;
    
    procedure TUniObservableEdit.ObserverAdded(const ID: Integer;
      const Observer: IObserver);
    begin
      inherited;
      if ID = TObserverMapping.EditLinkID then
        Observer.OnObserverToggle := ObserverToggle;
    end;
    
    procedure TUniObservableEdit.ObserverToggle(const AObserver: IObserver;
      const Value: Boolean);
    var
      LEditLinkObserver: IEditLinkObserver;
    begin
      if Value then
      begin
        if Supports(AObserver, IEditLinkObserver, LEditLinkObserver) then
          { disable the uniEdit if the associated field does not support editing }
          Enabled := not LEditLinkObserver.IsReadOnly;
      end else
        Enabled := True;
    end;
    
    procedure Register;
    begin
      RegisterComponents('uniObservableComponents', [TUniObservableEdit]);
    end;
    
    initialization
      Data.Bind.Components.RegisterObservableMember(TArray<TClass>.Create(TUniObservableEdit), 'Text', 'DFM');
    
    finalization
      Data.Bind.Components.UnregisterObservableMember(TArray<TClass>.Create(TUniObservableEdit));
    end.
    
    • Like 1
    • Upvote 2
  9. Maybe you can decrease runtime creation by putting 80 hidden uniPanels on your form (with property Visible:=False or Left:=-4000...).
    Then, in your loop, you just have to set the right properties of each uniPanel (using FindComponent method), without creating it first.  That's not a beautiful way but it can increase your performances.

     

    You can also decrease loading time by avoiding "LoadFromFile" method for each image; maybe you can try to put your images in the resources of your application: the size of your .exe/.dll will increase, but loading time could be faster.

     

    Finally, why not using LiveBindings instead of programmaticaly linking Captions, Texts and Names to your Tables ?

×
×
  • Create New...