Recent

Author Topic: Make main class wait for another class (console program)  (Read 10150 times)

BlueMoony

  • New Member
  • *
  • Posts: 34
Make main class wait for another class (console program)
« on: August 11, 2014, 09:49:36 pm »
Dear community,

don't really know this question resembles in this beginners section, but it looks like a beginners question to me.

What I would like to do:
1) Run console application which creates an additional class depending on its arguments
2) If this class is the controlling class, it should setup a few other classes and some timers. This class should not be freed nor should the program stop or exit.

Question: how to make the main class wait for the other class?

Some code I use:

DoRun function of main console application:
Code: [Select]
procedure Main.DoRun;
var
  ErrorMsg: String;
begin
  // quick check parameters
  // if wrong parameter -> exception
  {ErrorMsg:=CheckOptions('h','help');
  if ErrorMsg<>'' then begin
    ShowException(Exception.Create(ErrorMsg));
    Terminate;
    Exit;
  end;}

  // parse parameters
  if HasOption('h','help') then begin
    WriteHelp;
    Terminate;
    Exit;
  end;

  // Create settings object
  _appSettings:= TSettings.Create();

  // Check #parameters
  if(ParamCount <= 2) then
  begin
    // Amount of parameters is 1 or 2 (debug)
    // Running instance will be a controller
    _appSettings.AppType:= 'controller';
    ExecuteController();
  end
  else
  begin
    // More parameters = specific part
    // First fill in parameters
    _appSettings.AppType:= ParamStr(1);
    _appSettings.ZoneName:= ParamStr(2);
    _appSettings.Left:= StrToInt(ParamStr(3));
    _appSettings.Top:= StrToInt(ParamStr(4));
    _appSettings.Width:= StrToInt(ParamStr(5));
    _appSettings.Height:= StrToInt(ParamStr(6));
    _appSettings.ContentPath:= ParamStr(7);;
    // Next is check type & launch
    case _appSettings.AppType of
    'image':
      begin
        ExecuteImage();
      end;
    'banner':
      begin
        ExecuteBanner();
      end;
    'html':
      begin
        ExecuteHtml();
      end;
    end;
  end;
  ShowMessage('End of loop');
  // stop program loop
  Terminate;
  Exit;
end;

Main function itself (was auto generated)
Code: [Select]
var
  Application: Main;
begin
  Application:=Main.Create(nil);
  Application.Title:='Main';
  Application.Run;
  Application.Free;
end.                     

Code for executing the controller:
Code: [Select]
procedure TController.Execute();
var
  ZoneSetting: TZoneSettings;
  i: integer;
begin
      // Do other stuff (fill in array)
      CheckUpdate();
      ShowMessage('Updating enabled');
      Application.ProcessMessages;
end;
Code: [Select]
function TController.CheckUpdate():integer;
begin
  try
    begin
      _updateTimer := TTimer.Create(nil);
      with _updateTimer do
      begin
           Interval := 1000;
           Enabled := True;
           OnTimer := @OnTimerTick;
      end;
    end;
  except
  end;
end;
//______________________________________________________________________________
//
procedure TController.OnTimerTick(Sender: TObject);
begin
  ShowMessage('Timer ticked!');
end;

What happens:
1) Controller starts fine and fills in the array and creates other classes
2) It starts the timer and the timer runs fine (every second) until I hit the 'OK' on the 'Updating enabled' message. After that, the application quits.

How am I able to keep this all running? The other classes display several forms on the screen which need to be there all the time. The update function will change these forms at certain intervals through the array I filled in before. However, the application closes.

Methods I already tried:
1) Application.Idle in the controller
2) Application.Idle in the Main unit
3) While true do begin sleep(10000) end -> program hangs and so does the timer (no ticks)

Any suggestions? (like in how does a form wait for any event to occur? That object should somehow use some kind of loop no?)

Additional info:
Lazarus version 1.0.12
FPC: 2.6.2
x86_64-linux-gtk_2

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Make main class wait for another class (console program)
« Reply #1 on: August 11, 2014, 10:16:17 pm »
Can you explain one thing, you say "console application" and then you talk about forms.

Quote
Question: how to make the main class wait for the other class?
In general, it's possible with events. When subclass ends, it triggers an event.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

BlueMoony

  • New Member
  • *
  • Posts: 34
Re: Make main class wait for another class (console program)
« Reply #2 on: August 11, 2014, 10:39:47 pm »
Can you explain one thing, you say "console application" and then you talk about forms.

Quote
Question: how to make the main class wait for the other class?
In general, it's possible with events. When subclass ends, it triggers an event.

And with subclass ends, you mean when it destroys itself?

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Make main class wait for another class (console program)
« Reply #3 on: August 11, 2014, 11:02:50 pm »
Yes, similarly to OnDestroy event of form.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

BlueMoony

  • New Member
  • *
  • Posts: 34
Re: Make main class wait for another class (console program)
« Reply #4 on: August 11, 2014, 11:46:23 pm »
The main unit is a console application and so is the controller unit.
The controller unit has an array of other  units which are forms.
I want the forms to stay up all the time but since the execute procedure ends, so will the main function executeController(). This means the main unit will call the Terminate and Exit functions. This is not what I want since I started a TTimer in the Controller unit which will do stuff.

So how can I keep the controller unit and main unit "running"?

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Make main class wait for another class (console program)
« Reply #5 on: August 12, 2014, 05:57:37 pm »
It's unusual. Normally, Lazarus project runs in endless loop and operates events until main form is closed or until you call Application.Terminate;.
But you mixed console application with visual forms.
Solution should be to convert it from "console application" to normal project.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

BlueMoony

  • New Member
  • *
  • Posts: 34
Re: Make main class wait for another class (console program)
« Reply #6 on: August 12, 2014, 06:38:49 pm »
It's unusual. Normally, Lazarus project runs in endless loop and operates events until main form is closed or until you call Application.Terminate;.
But you mixed console application with visual forms.
Solution should be to convert it from "console application" to normal project.

So I have to use a Form application to get this working?

The reason why I used this approach is the following:
The main unit determines what type of the program should be launched based on the type and amount of parameters given. When no parameters are present, the main unit launches the controlling unit which doesn't need any form or dialogs. This controlling unit is somehow used as a service but isn't a real service. The controlling unit than executes the same executable with other parameters so the other functionality of my program is used which includes showing forms/dialogs.

As I would rather like the main & controlling unit be as lightweight as possible, I thought this was the best way to go. I only need those Form libraries when actually showing one.

So your solution is the following: convert the console application to a normal (form-based) application and don't show the form of the main unit? Or do you have something else in mind?

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Make main class wait for another class (console program)
« Reply #7 on: August 12, 2014, 07:06:32 pm »
Quote
As I would rather like the main & controlling unit be as lightweight as possible, I thought this was the best way to go. I only need those Form libraries when actually showing one.
In fact, it will not help you. Once you have one form in your program, whole LCL is included in compiled binary anyway, even if this form is never showed.
Converting from "console app." to normal application will not make your program bigger therefore. (Note that I never did a true measurement but I'm 99% sure).
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

BlueMoony

  • New Member
  • *
  • Posts: 34
Re: Make main class wait for another class (console program)
« Reply #8 on: August 12, 2014, 10:22:47 pm »
Quote
As I would rather like the main & controlling unit be as lightweight as possible, I thought this was the best way to go. I only need those Form libraries when actually showing one.
In fact, it will not help you. Once you have one form in your program, whole LCL is included in compiled binary anyway, even if this form is never showed.
Converting from "console app." to normal application will not make your program bigger therefore. (Note that I never did a true measurement but I'm 99% sure).

That is totally true, but those components/libraries will only be loaded when they are needed so the resource impact will be different. I have a tight amount of resources available so all the points I can save on should be used.

So to clear things up: there is no way to make the console application in the first place (main unit) "wait"? There is no available function/procedure that allows me to do actually the same thing a Form/Dialogbox does: wait/loop?

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Make main class wait for another class (console program)
« Reply #9 on: August 12, 2014, 10:53:10 pm »
I don't know. Maybe it is possible but I don't know how.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

BlueMoony

  • New Member
  • *
  • Posts: 34
Re: Make main class wait for another class (console program)
« Reply #10 on: August 13, 2014, 01:18:06 pm »
I don't know. Maybe it is possible but I don't know how.

Any other place I could ask? Thanks already for your time!

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Make main class wait for another class (console program)
« Reply #11 on: August 13, 2014, 01:29:39 pm »
Mailing list. Follow the links on the left (Lazarus -> Mailing List).
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: Make main class wait for another class (console program)
« Reply #12 on: August 14, 2014, 08:07:54 am »
You can always start a thread in main unit, that just keeps checking for your condition to do something.

mse

  • Sr. Member
  • ****
  • Posts: 286
n
« Reply #13 on: August 14, 2014, 09:41:05 am »
So to clear things up: there is no way to make the console application in the first place (main unit) "wait"? There is no available function/procedure that allows me to do actually the same thing a Form/Dialogbox does: wait/loop?
MSEgui has the unit "msenogui". If "msenogui" is in "uses" of the main program instead of "msegui" it will build a event driven application environment like a normal MSEgui application but without gui library. So one can use datamodules and all non-visual components as normal. Examples are here:
https://gitorious.org/mseuniverse/mseuniverse/source/attic/msedocumenting/mse/trunk/help/tutorials/nogui
I fear starting an application without gui and load gui libraries later on demand is not an easy task.

Fred vS

  • Hero Member
  • *****
  • Posts: 3256
    • StrumPract is the musicians best friend
Re: Make main class wait for another class (console program)
« Reply #14 on: August 14, 2014, 03:46:16 pm »
Quote
I fear starting an application without gui and load gui libraries later on demand is not an easy task.

Hum, you could also do it with fpGUIlib (library version of fpGUI) https://github.com/fredvs/fpGUIlib

 see fpc example => https://github.com/fredvs/fpGUIlib/blob/master/demos/demo_fpc/fpglibtest.pas

But at the moment only a few part of the huge set of fpGUI widgets is implemented in fpGUIlib.  :-X
« Last Edit: August 14, 2014, 04:24:40 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

 

TinyPortal © 2005-2018