Jump to content
Server Maintenance This Week. ×

zippScript Challenge


Rob P

This topic is 5586 days old. Please don't post here. Open a new topic instead.

Recommended Posts

Call me crazy but I want to modularize just about anything I can and here's what I've got to do:

I have a few utility scripts that depend on being on the correct layout so that it corresponds the the appropriate context (think about imports, exports, replaces, etc). I have one utility script that will allow me to specify how many tables I have and it will loop through all target layouts and do it's thing. Then I needed another script that did exactly the same things with just a different function. So, I thought, why not pass the target "action" script to this looping script as a parameter. Great idea, now I can just have my looping "go to this layout" script once and just pass it an action script.

I thought zippScript would be perfect for this. So, I'm passing 3 parameters (assuming that I will always be functioning on the current file...that could be a 4th parameter if necessary)--a script, script parameter, and control.

It works...but not exactly as I expected. The looping "go to layout" script runs just as it always did and zippScript is catching the parameters and interpreting them correctly BUT, it creating a call stack that is executed AFTER my looping script runs.

It kinda looks like this (it is simplified, so look at it in principle not something you could copy.

BTN: DO MY THANG

Perform Script [sUB: GO TO LAYOUTS; "sub: Find all records/-unused/resume"]



SUB: GO TO LAYOUTS

Set Variable [$i; 1];

//Set variables $script, $param and $behavior from the Get (scriptparameter)

Loop

 Go To Layout [specified by calculation; $i]

 Set Variable [$result ; zippScript ( get ( filename ) ; $script ; $param ; $behavior ) 

 Exit loop if [ // you've reached your max

End Loop



SUB: Find All Records

//self explanatory

So what you would expect for a call stack should look something like

BTN: DO MY THANG

SUB: GO TO LAYOUTS

//start loop

//loop 1

Go to Layout X

SUB: Find All Records

//exit

//loop2

Go to Layout X

SUB: Find All Records

//exit

//loop x

Go to Layout X

SUB: Find All Records

//exit

//end loop

//exit script

//exit script

What I get looks more like

BTN: DO MY THANG

SUB: GO TO LAYOUTS

//start loop

//loop x

Go to Layout X

//end loop

//exit script

SUB: Find All Records

SUB: Find All Records

SUB: Find All Records

It does not matter what control parameter I pass (halt, exit, resume, or pause). It does not change the behavior.

I'm I just nuts?

Link to comment
Share on other sites

I'm not sure how I can explain this; basically the first script (A) is passing the name of the script © I want run in the looping script(;). The looping script is supposed to fire off this passed script but instead it is stacking the execution of script © and executes it AFTER B is done. The stack should be like

A

B

C

B

C

B (not really running B over & over but it is a loop)

C

But what I get is

A

B

B

B

C

C

C

The loops execute and Then the C script executes for each iteration of the loop but it's too late becuase I'm no longer within the context of the layout I was supposed to end on with each iteration of the loop.

Link to comment
Share on other sites

It does not matter what control parameter I pass (halt, exit, resume, or pause). It does not change the behavior.

You're right compared to a almost identical embedded Applescript that calls an arbitrary filemaker script, the stack is when the applescript used, kept in order:

If [ IsEmpty ( Get ( ScriptParameter ) ) ] 

     Perform Script [ “scriptAS”; Parameter: 1 ] 

Else 

     If [ Get ( ScriptParameter ) = 10 ] 

            Perform AppleScript [ Native AppleScript: do script FileMaker script "Script2" ] 

     Else 

            Perform Script [ “scriptAS”; Parameter: Get ( ScriptParameter ) + 1 ] 

     End If 

End If




Which call's this "Script2":




Show All Records 

Show Omitted Only 

Loop 

      New Record/Request 

      Exit Loop If [ Get ( FoundCount ) = 10 ] 

End Loop  

This is first a recursive script that until the script parameter reaches 10 iterate. When the paramter then is 10 is the other script called.

Because this is a native filemaker step will the call to the external script be put on top of the stack of executions when watching it in the debugger, but when you substititute this call to an exteranal script with ZippScript, will it regardless the parameters be pushed way down in the order, until all recursions in the first script is unwounded.

This is a flaw in the plugin, not in filemaker as such, we should instead be overjoyed with the fact that it doesn't zap the previously created stack, but instead adds to the very end of the stack.

I do not like the fakt that the plugin is free, because you then can't expect the behaviour to be changed at all, when contributions or sponsoring are likely to be too meager.

The only method to circumvent this weird behaviour is to make the called script calling the controling script again carrying the remaining parameters for further scripting!

But it's interesting to know that something can change the order of a recursive script, so you could use the recursions to make the call to external scripts by unwinding the parameters via the recursion, and then make the following script course be made by the execution - in fact something similar to selfmodifying code!

:yourock::yourock::yourock::yourock:

--sd

Link to comment
Share on other sites

Okay, you know what an idea might be?

Make your 3 variables (script / paramater / behaviour) all global.

Make a new script, and insert the zip script syntax for calling a script, referencing all 3 global variables.

Insert this new script where you are currently calling your zip script in ... the main script.

Set behaviour when calling this script to pause.

... See if it works?

Link to comment
Share on other sites

Okay, well i just tried that and it didn't work...

There is something just screwy with the way zippScript does it's script executions, it always sticks it's script at the end of the stack.. while good for scheduled scripts i have to admit (and probably the reason for the way it operates) ... It won't work properly in the way you suggest as far as i can tell.

Link to comment
Share on other sites

I'm going to try the other 2 plugin. I found an interesting note in the readme of Eventscript regarding this very issue. It says that in FM 7, the execution was always placed at the bottom of the call stack but in 8 and 8.5 it was placed at the top and that this had nothing to do with the plugin but rather it was FM's code. I wonder if the developer stumbled on something and got it right that the developer of zipp did not get.

I'll know in a minute here.

Link to comment
Share on other sites

When it generalised knowledge, is it just something to act on - this what I had in mind when say the bit about the recursive part.

If results from previous scripts needs to be passed to the next step, couldn't the exit script paramter be utilized? In my mind does it still seem posible ...but I have to investigate it!

--sd

Link to comment
Share on other sites

I'm not sure I follow. Right now I don't need script results, I'm only passing script parameters (To scripts not From scripts). But otherwise, yes, the same would be true, you should be able to do the same with an exit script; but for this situation, that won't do you any good since the target script isn't even run until it reaches the end. At which point it's already too late.

Link to comment
Share on other sites

that won't do you any good since the target script isn't even run until it reaches the end.

Instead of too much explaning try to F6 chase the first script (you're getting thru all) in this template called the "theTest" ...what it does is that it assembles an execution order based on the scriptparamter, and lets the results wander thru.

--sd

stacking.zip

Link to comment
Share on other sites

From the EventScript's readme file, here's the paragraph who speaks about the script execution stack.

THE NEW FILEMAKER 8 BEHAVIOUR REGARDING TRIGGERED SCRIPTS

=========================================================

IMPORTANT! Please note that FileMaker version 7 and FileMaker version 8(including version 8.5) handle triggered scripts in different ways. FM 7 places the triggered script at the bottom of the script execution stack. This means that if you have 1 or more scripts already running at the time the trigger happens, these running (pending) scripts will complete execution before the triggered script runs.

On the other hand, FM 8 places the triggered script at the top of the execution stack. This means that any running (pending) scripts will be temporarily paused to allow the triggered script execution.

For some processes, this difference in behavior between FM7 and FM8 is an important thing to consider in the design and use of script triggers.

The execution priorities for the others pending scripts doesn't change.

For myself, I prefer to see my triggered scripts executed right away and I do appreciate a lot this new behaviour available since FM version 8. FM 8.5 has the same behavior as FM 8. By the way, EventScript has no merit in this "improvement". This is directly in the FM8 code and I can't do anything about this.

I have to confess this text is missing an important information: 'The context' !! What I meant here is if 1 (or more) script(s) is(are) running (or paused) when a script is 'action-triggered' thru a plug-in, then the triggered script will be placed at the very top of the execution stack. So the latest script (the manually triggered one) will be executed before the older ones.

Using the script debugger makes this phenomenon easier to see..

This behaviour is only relevant for a manual script triggered by an user's action and it does not concern the 'Rob P' case.

On the other hand, scripts triggered thru a plug-in from a FileMaker script command(let say: 'Set Field') will behave differently. e.g.:P the triggered script will always be placed at the bottom of the current execution stack. This behaviour is the same since at least FM7 and I don't think these behaviours will change.

In conclusion, action-triggers are not the same as Set-Field-triggers. They are not used for the same needs and they are not reacting in the same way.

HTH.

Link to comment
Share on other sites

Thank you, Gaston for your reply.

I did get a reply from Luk of myFMButler that DoScript 2.0 released today and might provide a solution to this unique situation.

I'll keep you posted as I think this has generated some interest.

Link to comment
Share on other sites

Hi all,

The way to do this, I think:

First:

mFMb_DS_SetIdleTimer( 0 ; "SemiSafeIdle" ) & mFMb_DoScript ( "[event]refresh window" )

It sets the number of seconds that the myFMbutler DoScript plug-in wil wait before going into the next idle processing for the given idle mode.

Then:

set variable (e.g. $x ) to

if ( True ; mFMb_DoScript( "" ; Get ( FileName ) ; “from scriptPaused: ” & Get ( ScriptName ) ; “Resume” ) ; False )

This for the sake of clarity, actually we want this:

mFMb_DS_SetTrigger( $x ; "ScriptPaused" )

I have made a mistake in the documentation there. The optional parameters are the same as with mFMb_DS_GetTrigger( { idleMode } ) . Sorry about that.

Finally:

mFMb_DS_SetAlarm( True ; "ScriptPaused" )

This enables the event to trigger.

It will not trigger as long as you don't pause a script. I've set the IdleTimer to 0, to have FileMaker check as often as possible, so the script should pause only a fraction of a second.

Now as soon as you pause your script, the event will (should) trigger and the other script will launch. It is launched with the "resume" parameter, so the running script resumes after the triggered script has finished.

That should do it.

Please send any bugs you encounter to Luk from myFMbutler. He forwards them to me, and I'll fix them if I can.

Link to comment
Share on other sites

Hi Rob,

Can I post files on this forum? A quick example file would maybe help you.

I posted one on our forum. http://www.clarify.net/peter/ScriptInterrupt.fp7

You are right. I did not explain very well.

The trigger code is something the plug-in evaluates during idle time. You should quote it. It will all become somewhat clear with the file link above.

Let me know how it went.

Link to comment
Share on other sites

The answer is yes you can post files on this forum... you just have to be in full reply mode (choose the reply option underneath someone elses post) or under the quick reply option.

RE: Omegagoh... When was Rob refferring to this plug-in? The only 3 plug-in's that have come up in the post (to my knowledge) are Eventscript, DoScript and zippScript

Link to comment
Share on other sites

Ah Peter, I see the logic... very interesting technique... and what's better it works :P

In the mean time, i have another question for you while you're here in this topic. Regarding the FM bug in windows where FM will not return to SafeIdle mode... is there a work around? I don't want to distrupt my users while they are entering data but I still want timed scripts to run... but only when the user hasn't done anythng for 30 seconds, any ideas regarding workarounds in the actual script?

Link to comment
Share on other sites

@Genx - thanks mate, I see it now.

Very frustrating: the reply I got from Filemaker: engineering is aware of it, but didn't give a schedule when it will be fixed.

That's really the only way to solve it completely. FileMaker should fix the bug in their engine. The way to get bugs fixed a FileMaker? Generate statistics. Massively submit a bug and it pops out in their charts. Just one belgian guy submitting some obscure bug won't do it.

What could you do more? Register user activity in a file variable - keep the time in it - whenever they do something, like clicking a button. Use that in your trigger as a condition - compare it with Get ( CurrentTimeStamp ). You know they are still active that way. But it doesn't cover a user just typing away, without clicking anywhere.

Another one would be checking with Get ( RecordOpenState ).

If the record is closed, it won't be much of a problem if you interrupt them with a script.

Maybe a combination of both. Maybe somebody else knows some other technique.

The Mac's behaviour isn't very useful either. Clicking a button on the Mac ( or Windows ) doesn't qualify as "doing something", according to FileMaker's idle engine. At least that one you can work around with the variable trick, but you need a script behind every button.

I don't know. I guess we have to wait for FileMaker to fix it.

Link to comment
Share on other sites

This topic is 5586 days old. Please don't post here. Open a new topic instead.

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
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.