Jump to content
Sign in to follow this  
Sibolo

Recursive scripts

Recommended Posts

I am analyzing some script's performance and have come across this situation a few times. Basically in some scripts you need to wait for a specific condition to be true then execute the code and get back to the start waiting for the condition to be true again.

Many times I see it solved in this way (only an example):

Wait for condition;

execute code;

call script again;

//Script.sqf
waitUntil {somecondition};
code;
code;
code;


execVM "script.sqf";
if (true) exitWith {};

I would like to know the pros and cons, and if this could be improved or done in a completely different manner that will give better performance as this script is going to be ran several times.

Thank you.

Edited by Sibolo
mistake

Share this post


Link to post
Share on other sites

Use a loop instead.

Also the last line is obsolete.

Share this post


Link to post
Share on other sites

Hi,

likePvPscene said, make a loop. Like this:

while {true} do {
waitUntil {somecondition};
code;
code;
code;
};

Also, if you're planning to run a SQF file more than, let's say, three times, make it a function instead of execVMing it.

Like this:

myFunction = {
code;
code;
code;
};

while {true} do {
waitUntil {somecondition};
call myFunction;
};

Or like this:

myFunction = compile (preprocessFileLineNumbers "Script.sqf");

while {true} do {
waitUntil {somecondition};
call myFunction;
};

Share this post


Link to post
Share on other sites

Is there any circumstance a


[left][color=#007700][font=monospace]while {[/font][/color][color=#0000BB][font=monospace]true[/font][/color][color=#007700][font=monospace]} do { 
[/font][/color][color=#007700][font=monospace]...
...
};
[/font][/color][/left]


loop will break out...some times I've seen it used like this:


//Script.sqf
while {true} do {
waitUntil {somecondition};
code;
code;
code;
};

execVM "script.sqf";
if (true) exitWith {};

and I interpret this that to be sure the script will always be active you put that execvm at the end just in case the loop breaks.

Share this post


Link to post
Share on other sites

It will never break out. true is always true :D

This loop, however, could break out:

while {xyz} do {};

by setting xyz = false;

So, if you want an endless loop, just use true as condition.

Share this post


Link to post
Share on other sites

Yet another alternative:

while {true} do {
	Aloop = "running";
	// code
	if (!letAloop) exitWith {Aloop = "stopped";};
};

this willbreakout a "while {true}" loop from running by modifying the "letloop" variable externaly. Almost the same as:

while {letAloop} do {
	// code
};
// this will do the same minus the "onLoopEnd" event you get with exitWith, which may come handy
// minus the possibility of using more cases for the loop state other than boolean.

one can also terminate a certain loop by invoking "terminate loop_function_handler;", which, from my usage, feels abrupt and less clean.

loop_function = {
while {true} do {
 // code
}
};

loop_function_handler = [] spawn loop_function;

and stop loop execution with:

terminate loop_function_handler;

In regards to performance I can't really tell but CBA as a benchmarking functionality which you could run different alternatives against.

Share this post


Link to post
Share on other sites

There is nothing wrong with recursion, but I'd rather make use of a "private function" or two as in:

private ["_fibonacci"];

_fibonacci = {
  if (_this < 2) exitWith { _this };

  ( ((_this - 1) call _fibonacci) +
    ((_this - 2) call _fibonacci))
};

(_this call _fibonacci)

Sure, you could write this function without private function:

if (_this < 2) exitWith { _this };

( ((_this - 1) call GLOBAL_fibonacci) +
 ((_this - 2) call GLOBAL_fibonacci))

But IMHO that's not so nice, since the function get's it's global name outside the function, while we need to know that name inside the function... bääh :)

Also the first version _could_ be faster, since the variable lookup for a private function _might_ be faster, than that for one in global scope. Actually I'm pretty sure that this is true.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×