Jump to content
Bert-Jan

Large project does not start

Recommended Posts

Hi all,

 

In the last few months I build an app for iOS and Android which expanded rapidly due to customer requests.

 

It is basically one unit with one main tabcontrol. Most tabItems have tabcontrols in them up to three levels. So many forms with many objects like rectangles, buttons and listboxes.

 

Lately the IDE became very slow and crashed frequently. Today, after adding a new tabItem and saving and closing the project, the whole project does not open again. I believe it is too heavy now.

 

My question is: what can I do to keep the IDE afloat and still expand the project?

 

Are there any best practices to develop a large multi device app?

 

My Windows 10 PC has 64 GB memory.

Edited by Bert-Jan

Share this post


Link to post
2 hours ago, Bert-Jan said:

Hi all,

...

My Windows 10 PC has 64 GB memory.

Good Anders, "On-Demand" is my favorite approach when it comes to visual components!

I think that the biggest problem of "our dear" IDE is the inheritance of the online analysis of the language itself, that is, "if the type is not in agreement, then, from now on, everything will also not be"!
Even now with the "LSP" protocol in greater use!

 

This time, everything is evaluated in real time, and, in the case of visual components, the thing gets even more terrible, because, in addition to the type, we still have the resources consumed by the components themselves, mainly the visual (graphical) part.

 

In terms of "On-Demand", we still have the type analysis, however, the graphic resources are not being loaded yet. Therefore, one less weight to carry the project.

To decrease the load a little, you could have everything that is graphically shown, that is, that is repeated in many forms, you could save in templates, for example, using "Frames", or even the inheritance of forms, which could have less impact on the project load. Not to mention that, if there are open connections to services, external or not, such as the Database, this also contributes to increase the load on the IDE.

 

I have a test project, where I use a "TFrame" (unit uMyFrameModel1.pas)  to populate a "TGridPanel" (in unit uFormMainExec.pas), and, the frame containing its components, "On-Demand" are created only at the right time! So, a lot already helps in the process of loading as a whole!

 

image.thumb.png.e58350a4ea2faf69d82be94ed7a2dde7.png

// a Frame is like a TForm, then... *of course, no at all!
...
lFrame := TfrmMyFrameModel1.Create( grdpnlOnTheForm ); // The Killer!
... // for last, when all it's ready:
lFrame.Parent := grdpnlOnTheForm;
...

 

But of course, I don't know how to scale your problem! It's just my speculation.

I don't know if I was clear to try to analyze the issue? Sorry !!!

 

hug

Edited by emailx45
  • Thanks 1

Share this post


Link to post

Thank you both. Does this mean I have to create the components programmatically? 

Share this post


Link to post

[badmorning mode]

Yes the Delphi IDE performs at is best as:

- You create all components manually 

- Do not use form/frame inherentance

- Disable all code- and error insight features.

- Use external compiler

 

it's Embarcadero's believe that the IDE is best used as a luxury notepad.

(but then you better use notepad++) 🙂

 

but hey, what else you gonna do with the few thousand dollars of the cost of Delphi 🙂

 

[/badmorning mode]

 

 

Edited by mvanrijnen
  • Like 1
  • Haha 2

Share this post


Link to post
11 hours ago, Bert-Jan said:

Thank you both. Does this mean I have to create the components programmatically? 

As your project is already committed, I think it's time to review some steps ... so, in order not to lose all the work, I would create a new project, and, little by little, I would add the units and evaluate where the bottleneck really begins. .. understood?

 

But maximum, you will lose a few hours, and, for free, gain some new way of seeing things. That is, this is a learning experience, not a curse!

Share this post


Link to post
11 hours ago, Bert-Jan said:

Does this mean I have to create the components programmatically? 

Yes.

I usually use a simple factory pattern. It briefly goes like this (view = frame):

  1. Create a "view registry" class.
    This class wraps a dictionaly that maps between a view interface and a class type.
  2. Move all your stuff into frames.
  3. For each frame assign them an interface and register the interface and the view class in the view registry.
  4. Create a "view manager" class.
    This class wraps a TDictionary<TGUID, TView> that contains the currently active view instances and is also responsible for creating new views.

So something like:

 

View (i.e. frame) abstract base class and API:

unit Foo.Views.API;

interface

type
  IView = interface
    ['{4057A1F4-F22C-4CCF-89DE-9F4AE2E790DE}']
    procedure Initialize;
  end;

type
  // Abstract base class of your views.
  TView = class abstract(TFrame, IView)
  protected
    // IView
    procedure Initialize; virtual;
  end;
  
  TViewClass = class of TView;
  
type
  IViewRegistry = interface
    ['{B4EC0F81-24DF-41D9-BF8A-CE0D9958C9A9}']
    procedure RegisterView(const GUID: TGUID; ViewClass: TViewClass);
    procedure UnregisterView(const GUID: TGUID);
    function FindView(const GUID: TGUID): TViewClass;
  end;

 type
   IViewManager = interface
     ['{B4EC0F81-24DF-41D9-BF8A-CE0D9958C9A9}']
     function OpenView(const GUID: TGUID): IView;
     procedure CloseView(const GUID: TGUID);
     function FindView(const GUID: TGUID): IView;
   end;

implementation
  ...
end.

 

The API of a single view:

unit Foo.Views.MyView.API;

interface

type
  IMyView = interface
    ['{063646E3-FB0D-4B8C-984A-A5E54F543651}']
    procedure FooBar;
  end;

implementation
end.

 

The implementation of a single view:

unit Foo.Views.MyView;

interface

uses
  Foo.Views.API,
  Foo.Views.MyView.API;

type
  // Trick to get the IDE to behave without registering the frame in a package
  TFrame = TView;
  
  TMyView = class(TFrame, IMyView)
  protected
    // IView
    procedure Initialize; override;
    // IMyView
    procedure FooBar;
  end;

implementation
  ...
intialization
  // Register our implementation of the IMyView interface
  ViewRegistry.RegisterView(IMyView, TMyView);
end;

 

and then you "just" have to

 

Implement IViewRegistry and IViewManager

unit Foo.Views.Manager;

interface

uses
  Foo.Views.API;

function ViewRegistry: IViewRegistry;
function ViewManager: IViewManager;

implementation

type
  TViewRegistry = class(TInterfacedObject, IViewRegistry)
  private
    FRegistry: TDictionary<TGUID, TViewClass>;
  protected
    // IViewRegistry
    procedure RegisterView(const GUID: TGUID; ViewClass: TViewClass);
    procedure UnregisterView(const GUID: TGUID);
    function FindView(const GUID: TGUID): TViewClass;
  end;
  
var
  FViewRegistry: TViewRegistry;
  
function ViewRegistry: IViewRegistry;
begin
  if (FViewRegistry = nil) then
    FViewRegistry := TViewRegistry.Create
  Result := FViewRegistry;
end;

procedure TViewRegistry.RegisterView(const GUID: TGUID; ViewClass: TViewClass);
begin
  FRegistry.Add(GUID, ViewClass);
end;

procedure TViewRegistry.UnregisterView(const GUID: TGUID);
begin
  FRegistry.Remove(GUID, ViewClass);
end;

function TViewRegistry.FindView(const GUID: TGUID): TViewClass;
begin
  if (not FRegistry.TryGetValue(GUID, Result)) then
    Result := nil;
end;

type
  TViewManager = class(TInterfacedObject, IViewManager)
  private
    FViews: TDictionary<TGUID, IView>;
  protected
    // IViewManager
    function OpenView(const GUID: TGUID): IView;
    procedure CloseView(const GUID: TGUID);
    function FindView(const GUID: TGUID): IView;
  end;

function TViewManager.OpenView(const GUID: TGUID): IView;
begin
  if (FViews.TryGetValue(GUID, Result) then
    Exit;
  
  var ViewClass := ViewRegistry.FindView(GUID);
  if (ViewClass = nil) then
    Boom!
    
  Result :=  ViewClass.Create;
  FViews.Add(Result);
  
  Result.Initialize;
end;

...etc. etc...

end.
  • Like 1
  • Thanks 1

Share this post


Link to post
1 hour ago, Bert-Jan said:

It seems I've got some homework.

Be advised, that in some countries, during these times, working any other way is currently prohibited and may incur hefty fines.

  • Haha 3

Share this post


Link to post
4 hours ago, Dany Marmur said:

Be advised, that in some countries, during these times, working any other way is currently prohibited and may incur hefty fines.

How would be for Amsterdan-Girls from De Wallen?  :classic_cheerleader: :classic_rolleyes:

Edited by emailx45

Share this post


Link to post
10 hours ago, Dany Marmur said:

Be advised, that in some countries, during these times, working any other way is currently prohibited and may incur hefty fines.

True. I always work at home. For more than 15 years now.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×