> (Example: if you open a window and then do CALL FORM before you issues a
DIALOG command,
> exactly what happens related to the form events? Not gonna tell you. Go
to the
> 4D World Tour and let JPR tell you!)

You seem excited about the event ;-) Keep in mind that not everyone can
attend because they either live to far away, have a scheduling conflict, or
are reading these posts in the future. Unless they invent a time travel
machine, it won't be possible to attend...Ultimately, if information isn't
in the docs (language ref, tech notes, tips, recorded sessions, etc.), it's
easily lost or ignored.

As far as the sequence of events goes, it's basic information that should
be in the documentation. There's nothing advanced about it and it's nothing
that should be secret. It's a bit of the mechanics that it's important to
understand so that you don't tie yourself in knots. Here's how it works
(I've posted it here before):

* When you call Open window (etc.) a 'queue' is created. This is *before*
any form is shown. So, the queue is a property of the window, not the form.

* You can post code blocks to the queue via CALL FORM *as soon as the
window reference is returned.*

* ...but then there's no form context to execute the command(s) you've
supplied.

* Once you open the form, On Load runs. *Your queued commands are still in
the queue.*

* After On Load, the queued commands are executed in order. The code you
pass in through CALL FORM is held in a First In First Out structure. That's
what a queue is. 4D's CALL WORKER and CALL FORM are 100% reliable about
executing code in the sequence it was received. That's a promise and it
makes things a lot simpler than they might otherwise be. Since this is
FIFO, not truly asynchronous or a stack (LIFO), the code is executed in the
order that you sent it. So, the overall sequence of events listed above
breaks down like this:

Open window    Queue is created
CALL FORM      Commands are posted to the queue pending execution
DIALOG, etc.   On Load runs pretend that you use CALL FORM here
Execute        The commands you posted before calling DIALOG (etc.) run,
then the ones from your On Load phase.

For illustration, let's say that you're logging something with these calls.
For this case, let's say it's numbers in sequence.

$winref:=Open window
CALL FORM($winref;"LogThingy";1)
CALL FORM($winref;"LogThingy";2)
CALL FORM($winref;"LogThingy";3)

DIALOG("MyForm")

// Form method
On Load
   CALL FORM($winref;"LogThingy";4)
   CALL FORM($winref;"LogThingy";5)
   CALL FORM($winref;"LogThingy";6)

That's the sequence *in the code*, here's the sequence *in execution*

Open window
On Load
LogThingy(1)
LogThingy(2)
LogThingy(3)
LogThingy(4)
LogThingy(5)
LogThingy(6)

I've made that as simple to follow as I can but, in truth, it's pretty hard
to follow if you start mixing CALL FORM in with loading the process and the
form. In this context, the command is more like

    DEFER METHOD

The current process/thread of control is consuming some code - and you're
adding new code to the end of that. I won't talk about the dangers inherent
in unsupervised uses of GOTO or self-modifying code. But, those of you who
remember those subjects  know what I'm talking about. As a
sanity-preserving measure and to make life easier for the next programming,
here's my recommendation:

    Make the code's order in the Method Editor match its order of
execution, as much as possible.

There are times when you'll want to mess with that...there are times when
it's a solid idea to go a different way...but as a rule of thumb, I'd
advise against writing code that takes a lot of mental energy to track.
With CALL FORM, you have to keep in mind that *it does not run where you've
typed it.* It runs at the end of the current code in the context you push
the code into. Actually, I should make a distinction between CALL FORM and
CALL WORKER here. If you've got CALL FORM, about the only funny bit is this
business described above. In the normal lifecycle of a form and it's code,
CALL FORM is a pretty natural fit. It can be handy, for example, to post a
CALL FORM to yourself. Apart from fancy reasons...this can also help get
around glitches in 4D's execution cycle. Many of you will remember using
POST KEY in the past. Just a few days ago I couldn't get a list row
highlight to work (no idea why) so I appended a CALL FORM callback and it
worked out fine.

With CALL WORKER it's *much* easier to tie yourself in knots. Depending on
what your worker does, there may be times when it makes sense to CALL
WORKER on yourself. That does get confusing. It can also get unpredictable
because other events may arrive from other processes before your deferred
code is executed. In such cases, I've found it easier to avoid self-calling
workers going through the queue. For example, imagine a worker that starts
by initializing some data it needs. A C_OBJECT or something. If you post
some code back to the queue to complete that task, how do you know that
some other task won't hit the queue from another process and mess things
up? You don't and you can't. (Unless you want to use semaphores. Ugh. Kind
of defeats the purposes of workers, a bit.) So, don't post the code - run
the code. So long as you are running code, queued requests are still
waiting. So, you can call back into your worker stuff _in the current call
chain_ and nothing will _ever_ interrupt that. (CALL FORM and CALL WORKER
are _not_ interrupts.) This works out a lot more smoothly. It's pretty easy
to determine if you're calling yourself and make the code branch (run
inline vs. post to deferred execution queue) so this needn't be a real
burden.

Urrrr. Right. Like I said earlier, we need to get enough of us into the
weeds on this stuff to start talking about more important issues. I guess
I'll just stick a pin in that for now...

P.S. This is all off the top of my head, so if I've been cryptic, unclear,
or wrong about something - feel free to ask a question or call me out.
**********************************************************************
4D Internet Users Group (4D iNUG)
FAQ:  http://lists.4d.com/faqnug.html
Archive:  http://lists.4d.com/archives.html
Options: http://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:4d_tech-unsubscr...@lists.4d.com
**********************************************************************

Reply via email to