Board index » cppbuilder » Where should i call my main loop?

Where should i call my main loop?


2004-05-23 10:21:13 PM
cppbuilder92
Hi all,
In my application i'm having while loop that should run until
the user press the 'Exit' key -
void MainLoop( void )
{
while ( !ExitFlag )
{
Task1();
Task2();
Task2();
Application->ProcessMessages();
}
}
My problem is - where should i call this function?? i tried to
call it from here
__fastcall TForm1::TForm1( TComponent* Owner )
: TForm( Owner )
{
MainLoop();
}
and also i tried to call it from the 'FormCreate' event and from
the first call to 'OnPaint' event, but in all this cases the form
was not showed on the screen.
What i did eventually was to start 100ms timer in the first call
to the 'FormShow' event, in the timer event i set the timer OFF
and i called to the 'MainLoop', it's working well but it's looks
to me like a very Twisted way do that, becouse who ensures me
that after the 100ms the form will finish it's creation? and if
it finish it's creation (+ it's display) and it's taking it only
5ms to do that, then i just wasted 95ms at start...
I want to call the 'MainLoop' function RIGHT AFTER the form has
been created and shown, where should it be?
Thanks
Ramy
 
 

Re:Where should i call my main loop?

"Ramy" < XXXX@XXXXX.COM >wrote:
Quote
[...] where should it be?
Use the OnActivate event:
void __fastcall TForm1::Activate(TObject *Sender)
{
static bool AlreadyLooping = false;
if( !AlreadyLooping )
{
AlreadyLooping = true;
// call the loop
}
}
~ JD
 

Re:Where should i call my main loop?

Thanks very much!
By the way i never understood what 'static' means, what's the
different between static and a global variable? is it better
approach to use in this case -
static bool AlreadyLooping = false;
inside the function, instead of using a global variable like -
bool AlreadyLooping = false;
??
Which wayis better and why?
Thanks!
Ramy
"JD" < XXXX@XXXXX.COM >wrote:
Quote

Use the OnActivate event:

void __fastcall TForm1::Activate(TObject *Sender)
{
static bool AlreadyLooping = false;

if( !AlreadyLooping )
{
AlreadyLooping = true;
// call the loop
}
}

~ JD
 

{smallsort}

Re:Where should i call my main loop?

And another question, why when the program is running in my
loop, the form does not close when i click with the mouse on the
'Close' Icon ( 'X' ) of the form, although that in this loop i
wrote -
Application->ProcessMessages();
?
Ramy
 

Re:Where should i call my main loop?

"Ramy" < XXXX@XXXXX.COM >wrote:
Quote
By the way i never understood what 'static' means, what's the
different between static and a global variable? is it better
approach to use in this case -

static bool AlreadyLooping = false;

inside the function, instead of using a global variable like -

bool AlreadyLooping = false;
Global variables should be limited as much as possible. Since
OnActivate is the only function that needs to 'see' the
variable, it doesn't need to be global but it does need the
'static' modifier to keep it around for the next time the
function executes.
If it wasn't static, if the user deactivated the form and then
reactivated the form, the loop would be called again with each
Activation.
IOW : non-static variables are allocated when the function is
called and deleted when the function returns. Static variables
hang around until the class is destroyed which in this case is
the form.
~ JD
 

Re:Where should i call my main loop?

"Ramy" < XXXX@XXXXX.COM >wrote:
Quote
[...] when the program is running in my loop, the form does
not close when i click with the mouse on the 'Close' Icon
( 'X' ) of the form,
Comment out the call to the loop in the OnActivate and see if
it will close.
If it does close after you comment out the loop, show the
actual code for the loop. Otherwise the problem is else where
in your code.
~ JD
 

Re:Where should i call my main loop?

"Ramy" < XXXX@XXXXX.COM >wrote in message
Quote
My problem is - where should i call this function??
What do your tasks actually do? You would probably be better off moving the
loop into its own worker thread instead.
Gambit
 

Re:Where should i call my main loop?

It's a communication program, there is a Timer-Tick that do the
transmit, and the tasks in the loop are preparing the command
buffer to be transmit and they also wait for the slave reply and
when it's recieved they check the reply and handle it.
I don't know how to work with threads, what is it good for? is
it hard? how do i start?
Thanks,
Ramy
Quote
What do your tasks actually do? You would probably be better off moving the
loop into its own worker thread instead.

Gambit
 

Re:Where should i call my main loop?

Hi JD, thanks.
You told me to put the call to the MainLoop in the 'OnActivate'
event handler, when i look in the help of the Builder (4.0) i
see this -
When a form is being created and its Visible property is
true , the following events occur in the order listed:
1. OnCreate
2. OnShow
3. OnActivate // You told me to call loop from here
4. OnPaint // Why not from here?
It's says that after the 'OnActivate' event there is ANOTHER
event which is 'OnPaint', so isn't it better to put your code in
this event instead of in the 'OnActivate' ?
And something strange, when i tried to put the code in the
'OnPaint' event a SpeedButton which i have on the form is not
display, i can press it and it's working but it's invisible, i
can see it only if i put the line -
Form1->Refresh();
after your line -
AlreadyLooping = true;
Any idea why does it happen?
Thanks,
Ramy
Quote
Use the OnActivate event:

void __fastcall TForm1::Activate(TObject *Sender)
{
static bool AlreadyLooping = false;

if( !AlreadyLooping )
{
AlreadyLooping = true;
// call the loop
}
}

~ JD
 

Re:Where should i call my main loop?

The problem is solve if inside the Form 'OnClose' event is set -
ExitFlag = true;
Then it's getting out of the loop and closing the application.
Ramy
"JD" < XXXX@XXXXX.COM >wrote:
Quote

Comment out the call to the loop in the OnActivate and see if
it will close.

If it does close after you comment out the loop, show the
actual code for the loop. Otherwise the problem is else where
in your code.

~ JD
 

Re:Where should i call my main loop?

"Ramy" < XXXX@XXXXX.COM >wrote in message
Quote
It's a communication program, there is a Timer-Tick that
do the transmit, and the tasks in the loop are preparing the
command buffer to be transmit and they also wait for the
slave reply and when it's recieved they check the reply and
handle it.
Sounds like there is no reason for the code to be in the main thread at all
then. You really should use a separate worker thread, especially since your
code is waiting for the reply before continuing. That can freeze up your
GUI, and calling ProcessMessages() in a loop is not a very good design in
general, and in fact can introduce subtle problems in the code (functions
being allowed to reenter themselves, timing issues, extra unwanted CPU
overhead, etc).
Quote
I don't know how to work with threads
Look at the TThread class.
Quote
what is it good for?
For running multiple tasks in parallel. A thread is its own separate unit
of execution. You can have multiple threads running at the same time.
Gambit
 

Re:Where should i call my main loop?

Hi Remy, i'm not waiting for reply in one single place and then
continue the loop when i get it... no, i'm running in the loop
again and again and again, and when i see that the COM Port
contains the number of bytes i was waiting for then i read them
and handle them, but the loop is running all the time also
when i'm waiting for the slave reply, the loop never stuck in
one place or one line, it's flow all the time.
I'll check about the threads issue, thanks.
Ramy
"Remy Lebeau \(TeamB\)" < XXXX@XXXXX.COM >wrote:
Quote

You really should use a separate worker thread, especially
since your code is waiting for the reply before continuing.
 

Re:Where should i call my main loop?

"Ramy" < XXXX@XXXXX.COM >wrote in message
Quote
Hi Remy, i'm not waiting for reply in one single place
and then continue the loop when i get it... no, i'm running
in the loop again and again and again, and when i see that
the COM Port contains the number of bytes i was waiting
for then i read them and handle them, but the loop is running
all the time also when i'm waiting for the slave reply, the
loop never stuck in one place or one line, it's flow all the time.
My earlier comments still apply. Especially with serial ports, you should
use a separate thread. Any operation on the port can delay since it is
accessing the hardware, so using a separate thread will prevent such delays
from effecting your main GUI code.
If you don't want to write the threading code yourself, then I suggest that
you find a third-party multi-threaded component that can access the serial
port for you.
Gambit
 

Re:Where should i call my main loop?

Thanks Remy, maybe i'll try it.
Quote
My earlier comments still apply. Especially with serial ports, you should
use a separate thread. Any operation on the port can delay since it is
accessing the hardware, so using a separate thread will prevent such delays
from effecting your main GUI code.

If you don't want to write the threading code yourself, then I suggest that
you find a third-party multi-threaded component that can access the serial
port for you.

Gambit