PDA

View Full Version : SQF functions over SQF scripts?



rwillis
Dec 12 2006, 18:52
How do I know when to use "call" to call a SQF function file over using "execVM" to call a SQF script file? Or basicly, what's the difference between SQF scripts and functions and how do I know when to use one over the other?

CrashDome
Dec 12 2006, 18:59
I cannot remember who explained it this way, but it is far more short and concise than I would have put it:

Functions halt the engine, execute, and return a value (which is why they are usually short and to the point - e.g. do a calculation).
Scripts run in parallel (which is why sleep command is used to prevent too much CPU usage - e.g. position a container below a helo while it is moving to give appearance it is carrying it).

Best advice I can give to newbies:
Use functions ONLY when the code is short and performs a single action to return a value.

rwillis
Dec 12 2006, 21:34
thanks

raedor
Dec 12 2006, 22:28
Best advice I can give to newbies:
Use functions ONLY when the code is short and performs a single action to return a value.
I'd even say: Only use functions when you _need_ a return (beside the script handle). http://forums.bistudio.com/oldsmileys/wink_o.gif If you don't need a return, just start a script.

Romolus
Dec 13 2006, 00:08
If you need a return from a script then you can also give it an array as parameter where the script puts the result(s) in. Since the array is given to the script by reference, you can read out the return values afterwards.

Something like this:
<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">_resultArray = &#91;0,&#34;&#34;&#93;;
_handle = &#91;_resultArray&#93; execVM &#34;resultScript.sqf&#34;;
// script runs and changes the _resultArray that is was given
waitUntil {scriptDone _handle};
_resultInt = _resultArray select 0;
_resultString = _resultArray select 1;[/QUOTE]

raedor
Dec 13 2006, 00:12
Indeed, didn&#39;t think of it that way so far. http://forums.bistudio.com/oldsmileys/biggrin_o.gif

UNN
Dec 13 2006, 05:48
Quote[/b] ]If you need a return from a script then you can also give it an array as parameter where the script puts the result(s) in. Since the array is given to the script by reference, you can read out the return values afterwards.

Yep, but it&#39;s has some restrictions. For example, you can use + or - on _resultArray, otherwise you loose your pointer to it.

Functions are also required when you want to guarantee run a succession of commands on an object, before the screen updates. Like setpos and setdir in a loop.

You don&#39;t stop functions like you do with scripts, when you hit escape to pause the game.

The games interal clock won&#39;t increment while using functions, unless told to using sleep (http://community.bistudio.com/wiki/sleep). See this (http://www.flashpoint1985.com/cgi-bin/ikonboard311/ikonboard.cgi?act=ST;f=71;t=55470;st=15) thread about functions and the sleep (http://community.bistudio.com/wiki/sleep) command.

Donnervogel
Dec 13 2006, 15:47
The games interal clock won&#39;t increment while using functions, unless told to using sleep (http://community.bistudio.com/wiki/sleep). See this (http://www.flashpoint1985.com/cgi-bin/ikonboard311/ikonboard.cgi?act=ST;f=71;t=55470;st=15) thread about functions and the sleep (http://community.bistudio.com/wiki/sleep) command.
There we are again with the lack of clear terminology... now what you said is misleading - kinda. Because we can&#39;t use the sleep command in functions (as in a function that returns a value as it was used before in this thread).
EDIT: just read your last comment in the other thread, so well. we still can&#39;t always use it http://forums.bistudio.com/oldsmileys/wink_o.gif It remains to be seen why it works in your example...

But in the "normal" case we can only use sleep in what Kegetys called an SQF function in the other thread, as opposed to an SQF script which is a script that uses the SQF syntax - but it&#39;s not really a function.

UNN
Dec 13 2006, 15:56
Quote[/b] ]we still can&#39;t always use it

Whats that got to do with anything? We are talking about executing a script with the three new Arma commands?

Don&#39;t take my word, or anyone elses for that matter. Try the example I posted yourself.

Oh and yes, always best to read all of a post.

Donnervogel
Dec 13 2006, 16:04
Quote[/b] ]we still can&#39;t always use it

Whats that got to do with anything? We are talking about executing a script with the three new Arma commands?

Don&#39;t take my word, or anyone elses for that matter. Try the example I posted yourself.

Oh and yes, always best to all of a post.
it has to do with everything, because what you found is probably some very special case. But the sleep command won&#39;t work when you execute a regular "function" (<-- that&#39;s the word you used) so now we have the problem of terminology, I don&#39;t understand what you are saying. If you say function I must assume you mean an SQF function, called with the call command. Then you statement is not really correct. It works in your example but it doesn&#39;t work in any case I tried when the SQF Function was in a separate file as opposed to a constant of type code as in your example. Maybe the interpreter analyses the code constant and figures it must be an SQF script because sleep is used. I don&#39;t know. As I said it remains to be seen why this works and most other cases don&#39;t.

However your statement could also mean that you talk about SQF scripts which behave differently from SQF functions but share the same syntax. Then we can use the sleep command of course.

But how am I supposed to know what you are talking about when you just say "function" which is atm often misused and you also talk about using the sleep command which is only allowed in scripts (normally)

UNN
Dec 13 2006, 16:26
Quote[/b] ]It works in your example but it doesn&#39;t work in any case I tried when the SQF Function was in a separate file

The why didn&#39;t you say that in the first place?


Quote[/b] ]But how am I supposed to know what you are talking about when you just say "function" which is atm often misused and you also talk about using the sleep command which is only allowed in scripts (normally)

I defined my version of what I think should be referred to as a function, long before this thread appeared. I even discussed it on the wiki. The only difference was, I said the term function based script should be dropped and we stick to just two types, like we did with OFP. Functions (*.sqf) and scripts (*.sqs). To cut it short, use call (http://community.bistudio.com/wiki/call_code) to execute functions. Everything else gets executed with the remaining commands.

As to why you can use call (http://community.bistudio.com/wiki/call_code) in that way, who knows. If it won&#39;t work in an external file (I&#39;ve yet to check that) then it might be down to scope. Using the call (http://community.bistudio.com/wiki/call_code) command with {}, in a script, allows you to share the scope of that script. However like I said in the other post, that could well be a bug that needs to be added to the Wiki. If it&#39;s not a bug, then we at least have to be aware of when you can and can&#39;t use it. For beginners it&#39;s probably better not to bog them down with minor details like using sleep with the call (http://community.bistudio.com/wiki/call_code) command when embedded in scripts. But I for one would like to know how things work and what options we have.

Either way, I&#39;m glad to know that someone has at least confirmed it as a fact, even if you find it misleading it&#39;s still a fact.  Now it can be added to the wiki bug list, for BIS to decided if it is or isn&#39;t.

CrashDome
Dec 13 2006, 16:37
Best advice I can give to newbies:
Use functions ONLY when the code is short and performs a single action to return a value.
I&#39;d even say: Only use functions when you _need_ a return (beside the script handle). http://forums.bistudio.com/oldsmileys/wink_o.gif If you don&#39;t need a return, just start a script.
I wouldn&#39;t.

That would take away a good chunk of patterns and practices capable with functions. In fact, I would recommend using less "scripts" be it sqs or sqf style simply because they are inherently less reliable.

A function that doesn&#39;t return a value: Ever hear of a "void" function before?

Coding practices should be clean and simple. By reducing to as many functions as possible (actual functions using call) you make code more portable, more reliable, and more adaptable. Scripts should be used simply to weather out code which loops such as checking for events or when executing mutliple functions concurrently that are not time-sensitive.

I made a discussion post on the biki yesterday to suggest calling functions which use execVM or spawn (a.k.a "scripts") "ArmA Scripts" and old sqs files "OFP Scripts". Functions called with call command would still be functions.

Reminds me.. I should check if anyone replied....

Hmm... Raedor, I replied back that basically if we call them "OFP scripts" regardless of using them in ArmA it might suggest that they are "old style."

Donnervogel
Dec 13 2006, 16:45
I didn&#39;t say it in "first place" because it&#39;s pretty clear that sleep cannot be allowed in a regular functions. Because it then can freeze the game for very long periods. A functions is there to perform a calculation or something that returns a value. This has to be done quickly so the script (or init-Line) that called it can continue with it&#39;s execution. If a script has to wait 60 seconds for a returning value because people use "sleep 60" in the function it can&#39;t continue (and as I understand it neither will the whole game continue) which obviously doesn&#39;t lead to the desired effect in most cases.


What I think is most important to beginners is that we precisely define what we are talking about. There&#39;s nothing more confusing if you try to get into a "language" than unclear definitions and a lot of exceptions. (That&#39;s also why I could never really grasp French grammar). And calling everything in an .sqf file a function is very unclear. Because we have two different types of code that are stored in an .sqf file. So the only thing that the different codes in an .sqf file have in common is their syntax (and that is only by convention, as you can use the "SQF Syntax" also in .sqs files, and I didn&#39;t try it but probably any text file format will work). But we need to distinguish between those types of code that we store in .sqf files somehow because we cannot use all commands in both types. The sleep command is a perfect example. And it also helps us to decide if we need to "call" or "execVM" the file to not get a compiler error. ANd the most important aspect is probably that we must distinguish between the fundamentally different workings of those two types of code. The "script" can run paralelly with other scripts and the game while the "function" halts the game and they get executed sequentially.

MrZig
Dec 13 2006, 16:46
If you are execing/execvming/calling a file (whether it be a script, a script function, or a function) once every 0.001 seconds, that does a simple check and ends (no wait, loop, etc) what would be THE most efficient way?

Exec?
ExecVM?
Call?

CrashDome
Dec 13 2006, 17:02
Use call... and make it a SQF "Function" you can preprocess

The fact you are controlling the interval externally (assuming from an SQF or SQS "script") means you can reduce it to the quickest and most efficient way to check something - i.e. "function"

Let me clarify something for everyone....

Calling preprocessed functions from within other preprocessed functions should be minimal simply to prevent function induced lag. However, good code flow is when you have an SQF or SQS "script" which is like a breakdown of the steps needed to complete your idea. Each "step" should be a short function which can be run to either check a value or do some sort of calculation or even to perform an action (like setPos). By breaking your idea into multiple functions you can use the "script" to run parallel each function("step") while controlling time intervals to allow the engine to run smoothly.

If you run everything wolely within a "script", you cannot control when the engine will pause your code to continue with the game core on the main thread. For people with low framerates it is very obvious that code does in fact pause. By putting your individual steps within functions you can better control where the pauses take place. And if you prevent functions from calling alot of other functions you prevent excessive delays in code execution. It&#39;s the balance of coding which is in itself an artform.

UNN
Dec 13 2006, 17:41
Quote[/b] ]I didn&#39;t say it in "first place" because it&#39;s pretty clear that sleep cannot be allowed in a regular functions. Because it then can freeze the game for very long periods.

There is absolutely no reason why that can&#39;t be the case, if BIS want to build that into their language. There are no irrefutable laws of nature that say it can&#39;t be done.

Clearly using sleep with the call command does not freeze the entire game. That fact started all this, or did you forget that, just then http://forums.bistudio.com/oldsmileys/smile_o.gif I also believe the Call command is not broken, but it may or may not, not be working exactly the way BIS intended.


Quote[/b] ]And calling everything in an .sqf file a function is very unclear. Because we have two different types of code that are stored in an .sqf file. So the only thing that the different codes in an .sqf file have in common is their syntax (and that is only by convention, as you can use the "SQF Syntax" also in .sqs files, and I didn&#39;t try it but probably any text file format will work).

Your missing my point, there is only one type of code that should be used in an function (*.sqf). Code thats designed specifically to be used with the call (http://community.bistudio.com/wiki/call_code) command. Any other code should be called using execVM (http://community.bistudio.com/wiki/execVM) or Spawn (http://community.bistudio.com/wiki/spawn), this should have the file extension (*.sqs). That way you know how the file should be used, even before you open it.

The most important aspects of functions have nothing to do with syntax. In a function, you can end each line with a wink for all I care. How it executes the code and what it returns, is the most important thing.


Quote[/b] ]ANd the most important aspect is probably that we must distinguish between the fundamentally different workings of those two types of code.

Yes, that’s exactly my point. Two different types of code only require two different descriptions. But unfortunately, I believe old style OFP scripts are still required in some cases? I&#39;m not exactly sure where, I think it&#39;s init.sqs. Although IMHO this single exception is easier to add as a sub clause.


Quote[/b] ] If you are execing/execvming/calling a file (whether it be a script, a script function, or a function) once every 0.001 seconds, that does a simple check and ends (no wait, loop, etc) what would be THE most efficient way?

If you mean like this?

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">WaitUntil {

Sleep 0.001;

&#60;Execute MrZig’s simple check&#62;;

};[/QUOTE]

Or in OFP style code:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">#Loop

~0.001

&#60;Execute MrZig’s simple check&#62;;

goto &#91;“Loop”&#93;[/QUOTE]

Then probably a function, so use the Call command. The reason I say a function is, scripts can’t loop any quicker that 0.001. There is a good chance they may take longer. So if you have such a short time span, only a function will guarantee the command(s) are executed when they’re supposed to. So in that case, function is the best way.

Edit:


Quote[/b] ]It works in your example but it doesn&#39;t work in any case I tried when the SQF Function was in a separate file

I just tested this in Arma:

Function.sqf:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">Player SideChat Format &#91;&#34;Time 1 &#58; %1&#34;,Time&#93;;

Sleep 5;

Player SideChat Format &#91;&#34;Time 2 &#58;%1&#34;,Time&#93;;

Sleep 5;

Player SideChat Format &#91;&#34;Time 3 &#58;%1&#34;,Time&#93;;[/QUOTE]

It was called from an Arma script using this:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">_Func=compile LoadFIle &#34;Function.sqf&#34;;

Call _Func;[/QUOTE]

And guess what, the sleep command works in pre-compiled, external functions to. The error message you probably saw, was caused through not pre-comiling the function.

CrashDome
Dec 13 2006, 17:56
whats the difference between preprocessfile and compile loadfile?


Quote[/b] ]this should have the file extension (*.sqs). That way you know how the file should be used, even before you open it.

I disagree. SQS files should only contain old-style syntax. Otherwise you can potentially break third-party apps like Chris&#39; OFP editor and such.

I use Crimson Editor myself and it codes according to file extension. If I start writing c-like syntax in an sqs file it&#39;s going to be confused as much as I will be.

UNN, can you verify that your sleep commands using call in a compiled function does not in fact pause the engine for 10 seconds and prevent anything else from running?

Romolus
Dec 13 2006, 17:59
In fact, I would recommend using less "scripts" be it sqs or sqf style simply because they are inherently less reliable.
Actually, I can&#39;t fully agree there.

What you said is all valid for regular programming, but game programming is something different.
For a game what makes or breaks it is how smooth it is running and that has pretty much top priority. If you have the best AI and the best looking graphics and all but it&#39;s running at 60 frames per minute, then you can throw it all away because it&#39;s useless.
Now if a regular program has a response time of 10s it might be tolerable.

And the case of choosing between a function or a script definitely affects performance, so regular coding practices can only applied after that is taken care of.

Most of the coding that we do for OFP or ArmA doesn&#39;t rely on getting done between two frames and usually can take much longer without having any side-effects.
For all cases where it&#39;s not necessary to have a fast execution time even on the expense of performance, I think scripts should be used instead of functions.
In fact if your function is taking too long then it just gets canceled and you&#39;re off worse than with a script. In that case scripts are more reliable than functions.

Also compared to regular programs with several million lines of codes, our OFP/ArmA scripts are tiny. If you loose oversight and get less reliable, portable and adaptable code because of using scripts instead of functions, then you&#39;re doing something else wrong.
Scripts can be written just as portable, adaptable and reliable than functions. What matters is the difference in execution which makes an impact on performance.

Following general programming practices without looking at how things work under the hood isn&#39;t a good thing. It&#39;s about knowing how to structure things in a given environment and adapting the rules to it instead of blindly following them.

So know about good programming practices, know WHY they&#39;re good, know about the difference between scripts and functions (and not to forget the quirks and things about all the commands) and apply all this to get good running code that does useful things in the first place and is adaptable and portable and all those nice things second.

UNN
Dec 13 2006, 18:02
According to the Wiki:

Pre-process:


Quote[/b] ]Returns preprocessed content of given file. Preprocessor is C-like, supports comments using // or /* and */ and macros defined with #define.

I can&#39;t find anything at about compiling code. But I&#39;m sure there is something in the Wiki that states it, makes code more efficent as once it&#39;s benn pre-compiled the first time Arma does not have to do it every time it&#39;s called.

I guess you could use something like:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">_Func=Compile Preprocess &#34;Function.sqf&#34;[/QUOTE]

In OFP you could not pre-process a function stored within an addon. Not sure if compiling it has the same restrictions. Add that the my list of things to check.

MrZig
Dec 13 2006, 18:06
Hold on, Nonono that&#39;s not what I&#39;m asking UNN.

It&#39;s aleady being execed/execvmd/called 0.001 times, I can&#39;t change that (I can&#39;t say how, it&#39;s a secret&#33http://forums.bistudio.com/oldsmileys/wink_o.gif

But every 0.001 it will be loading either an external script, or a preprocessed string. What is more efficient?

Calling a compiled proproccesed string every 0.001 seconds
(EVERY&#33; ) or
ExecVMing a .sqf every 0.001 seconds?

Here&#39;s my example.

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">
#lp
~0.01
;call ZigPreprocessedCode
;&#91;&#93; execvm &#34;ZigCode.sqf&#34;
;&#91;&#93; exec &#34;ZigCode.sqs&#34;
goto &#34;lp&#34;[/QUOTE]

Keep in mind that this isnt how it actually is, so DONT try and say that #lp and ~0.01 isnt efficient, because it&#39;s entirely different. I just want to know which execing type is more efficient.

And lets say that the file I&#39;m trying to open every 0.01 seconds question is this.

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">
IF &#40;&#40;getpos man select 2&#41; &#62; 30&#41; THEN {man setpos &#91;getpos man select 0, getpos man select 1, &#40;getpos man select 2&#41; - 0.1&#93;};
IF &#40;&#40;getpos man select 2&#41; &#60; 15&#41; THEN {man setpos &#91;getpos man select 0, getpos man select 1, &#40;getpos man select 2&#41; + 0.1&#93;}[/QUOTE]

This aint the actual file, just an example of how the real one flows.

CrashDome
Dec 13 2006, 18:15
@<hidden>

You should have read my clarification.

I know exactly what is running under the hood(figuratively speaking). However, as much as what you say is true, what you don&#39;t say is equally as bad.

You said "If you loose oversight and get less reliable, portable and adaptable code because of using scripts instead of functions, then you&#39;re doing something else wrong."

This is exactly what I am saying. If you simply write nothing but scripts you give less control of your code to maintain performance of the engine. However, in most cases this need not be true. I just tend to approach it from the other side of the field. I write functions. Then I control my functions by adapting scripts which give me more control over my code. If something breaks, yes it is bad code but I can better determine where the breakdown exists and control it even further.

This is one thing I never believed about game programming.. it is not inherently different then any other type of programming and most rules apply equally to help produce quality products. Only when the standards don&#39;t allow for proper functionality should you depart from good practices - NOT simply toss out standards because they might not fit under certain conditions which you might not encounter anyways.

If I understand your logic then I dont see what the purpose of functions are at all? Am I to assume you think functions are pointless?
On the contrary I think they are great. I can ensure my calculations execute (especially if using an object within the function) without change in state by anything. If I run scripts my object might not exists half-way through it. It is statistically remote, but a possibility none-the-less.

@<hidden>
I am familiar with what the wiki says.. I am more interested if there is a difference in the results (and what that difference is if it does produce different results)

This is an excellent discussion thread btw... I wish more were like this

Romolus
Dec 13 2006, 18:39
...This is one thing I never believed about game programming.. it is not inherently different then any other type of programming and most rules apply equally to help produce quality products. Only when the standards don&#39;t allow for proper functionality should you depart from good practices - NOT simply toss out standards because they might not fit under certain conditions which you might not encounter anyways.
I still don&#39;t agree.

A rule or good practices them self have no other value than reminding you about more complex things that are valid for a specific environment. Nothing more.
Every other use of a rule or good practices is a bad use. You could as well throw a dice instead of using a certain rule or good practice.

To know if your rule or good practice is applicable, you still have to know the complex reasoning behind it and the environment it is valid for. If you don&#39;t it isn&#39;t worth anything.

So asking about rules is absolutely pointless. What people should ask for is explanations about how things are and draw their own conclusions.

Question everything&#33;
If something is obvious, then it&#39;s easy and fast to explain and also to see that it really is. But by doing so you know for sure that things are that way and you&#39;re not just following a hollow rule.
That&#39;s the most basic quality control you can and should do.

Also when answering, I think it&#39;s also pointless to just state rules. For someone not knowing the things behind a rule, the rule itself has no value at all.
So I&#39;m at least trying to always give explanations instead of rules even if people get annoyed because it&#39;s getting too long winded abut things they don&#39;t even want to know because they think they can get away with more simple things http://forums.bistudio.com/oldsmileys/smile_o.gif



Commenting on your edits CrashDome:
My main point is that it&#39;s pointless following rules just because they apply for other cases.
I don&#39;t think functions are useless at all.
But there&#39;s absolutely no way in setting up easy rules that can tell you when exactly use a function or a script. What I mean is that you need to know the differences between the two and how this affects coding in various situations. This can&#39;t be taught by rules, this has to be learned by examples. There&#39;s no shortcut for that.

My second point that results from the first is that games are different than "normal" programs since performance is the major factor. First you need to be concerned about performance, and then about everything else.
So every rule or good practice you know from programming "normal" programs needs to be tested if it&#39;s still valid and if it doesn&#39;t put priority to something else instead.
I couldn&#39;t live without good programming practices, but I always have to question whether something is applicable in the specific situation or not.
Even programming practices for "normal" programs can be fundamentally different so that you have to decide which one you want to follow for a specific case. And with games it&#39;s even more tricky.

So having good coding practices is nice, functions are nice, scripts are nice, know how they work and how they affect performance. Know how commands work and know how they affect performance. If you do that, you automatically get your own set of rules to make your life easier, but are worthless for others who don&#39;t know the rest (,yet maybe) http://forums.bistudio.com/oldsmileys/smile_o.gif

Donnervogel
Dec 13 2006, 19:11
Edit:

I just tested this in Arma:
Ok I tested the function stuff with sleep. Now functions work with sleep. The error must have been on my side previously. I withdraw my point that sleep doesn&#39;t work in functions therefore.

However this behaviour is in contradiction with some entries on the Biki regarding functions. So I guess those need corrections.

UNN
Dec 13 2006, 22:49
@<hidden>


Quote[/b] ]UNN, can you verify that your sleep commands using call in a compiled function does not in fact pause the engine for 10 seconds and prevent anything else from running

It will halt the script it&#39;s being called from. But if you launch code with Spawn (http://community.bistudio.com/wiki/spawn) or execVM (http://community.bistudio.com/wiki/execVM), before calling the function, they will continue to run.


Quote[/b] ]I disagree. SQS files should only contain old-style syntax. Otherwise you can potentially break third-party apps like Chris&#39; OFP editor and such.

Chris&#39;s editor works fine with the new scripts. I&#39;ve already imported the commands, so there highlighted. I can post the file if anyone is interested, but I doubt I&#39;m going to add the syntax references. To be honest, as far as terminology goes. It&#39;s not like it&#39;s the of the world or anything. I&#39;m sure it will work itself out one way or another.


Quote[/b] ]I am familiar with what the wiki says.. I am more interested if there is a difference in the results (and what that difference is if it does produce different results)

I think pre-processing a file should be looked at along the same lines as formatting a string with %1...%9 e.t.c. Once it&#39;s formatted, you then compile it. If I understand your question?

@<hidden>


Quote[/b] ]it&#39;s a secret

Secrets are overrated http://forums.bistudio.com/oldsmileys/smile_o.gif


Quote[/b] ]But every 0.001 it will be loading either an external script, or a pre-processed string. What is more efficient?

Neither, you should pre-compile your code into a variable and call it with the Spawn (http://community.bistudio.com/wiki/spawn)  command if it needs to behave like a script. Or call (http://community.bistudio.com/wiki/call_code) if it can get away with being executed like a function.


Quote[/b] ]And lets say that the file I&#39;m trying to open every 0.01 seconds question is this.

setpos (http://community.bistudio.com/wiki/setPos) is ok on it&#39;s own.

@<hidden>

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">Most of the coding that we do for OFP or ArmA doesn&#39;t rely on getting done between two frames and usually can take much longer without having any side-effects.[/QUOTE]

For me it&#39;s the other way round and I can think of a few people who will need to use this info if they port their addons over. But I do see your point. I would try not bore novice scripters to death, in quite the same way http://forums.bistudio.com/oldsmileys/smile_o.gif I think the info should be tiered, so you can progress through the various levels of detail.


Quote[/b] ]Ok I tested the function stuff with sleep. Now functions work with sleep. The error must have been on my side previously.

I tried to execute the same function from an objects init field, that didn&#39;t work. The sleep (http://community.bistudio.com/wiki/sleep) keeps throwing up an error. From a script it&#39;s ok.

CrashDome
Dec 14 2006, 14:29
Thanks for testing UNN.

@<hidden>

I guess we&#39;ll have to settle at disagreeing. I see your point but I still dont agree. I tend to believe alot of practices are based on performance and efficiency and do apply to games versus "normal" applications.  There is a difference between retrieving thousands of SQL datarows within an appication lifetime and retrieving thousands of packets of MP info from other clients but the end goal of acheiving high performance and efficiency is always the same. These coding practices are not developed by retards (atleast the ones I use). They are in fact a development of what is optimal underneath the language you are using and developing good practices with scripting in ArmA should not be ignored simply because it is not "normal". I agree there will be times a person who truly knows what they are doing will create the best code, but what I am suggesting is tried and true practices that teach the new guys to get started without writing spaghetti all the time. It is no different than providing a coach to play football versus having everyone learn the hardway by facing them off with a bunch of pros and watching their bones get broken all the time. What you are suggesting is that the new guys are basically SoL and need to get pushed out of the nest from day one and if they hit the ground then it&#39;s their own fault.

Romolus
Dec 14 2006, 19:27
I think you guys are getting me a bit wrong here http://forums.bistudio.com/oldsmileys/smile_o.gif
I&#39;ll explain what I mean by the example of the question that MrZig asked.

He wanted to know which of the commented-out lines would be the best to use:
<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">#lp
~0.01
;call ZigPreprocessedCode
;&#91;&#93; execvm &#34;ZigCode.sqf&#34;
;&#91;&#93; exec &#34;ZigCode.sqs&#34;
goto &#34;lp[/QUOTE]
Now having some insights into this topic, can you honestly give him a straight and short answer in form of rules, that is really true for what he&#39;s trying to do?
I think I can&#39;t and here&#39;s why:

If I tell him that using functions for everything is good coding practice and he goes on and implements 50 functions that may be a bit heavier than the example he posted and runs them every 0.001s, can he expect that to be working fine?
The advice or the rule itself may have its merits but then he doesn&#39;t know in what cases it has merits and therefor can&#39;t use the rule for his benefit. To do that he needs to know the reasoning behind the rule.

Now I tell him to use scripts as much as possible and he&#39;s running the same 50 scripts every 0.001s and doing a file access every time (or is that cached in ArmA*?). I doubt that he&#39;ll be happy with that rule either, at least as long as he doesn&#39;t know the reasoning behind it.

What am I supposed to tell him? For some things there is just no straight and short answer that is generally true.
That leaves me with basically three options:

- Explain him how (according to my experience) the thing works under the hood and where he should look for traps so that he can go and not just apply it to his current problem but maybe for all the coming problems that he&#39;s going to face in that direction as well.

- Tell him to just try for himself and see what happens because doing so would probably only take about 15 minutes and he&#39;ll get results that specifically match his problem and for sure is faster than me trying to explain the whole thing. At least this will solve his current problem and maybe even give him some insights to tackle the next one.

- Tell him that it doesn&#39;t really matter and he should throw a dice to decide. For me that&#39;s the same as telling him to go by some kind of rule that might or might not apply to his specific case, after all I don&#39;t really know the details to judge myself if such a rule would be good to apply there or not. Also the time it takes to get the details (if he&#39;s even willing to share them) will probably take longer than the first two options above.


And for rules or good practices, you say it yourself:

They [the coding practices] are in fact a development of what is optimal underneath the language you are using.
What kind of language?
ArmA scripting, C++, Haskel or even Assembler for some weird Motorola chip?
You need to know the reasoning behind those rules and what they were geared for to be optimal to use them properly.
In fact, it might even be better to write spaghetti code than applying coding practices from other languages/project types/plattforms/..., because the reasoning behind every rules is anything but universal.
Hell, even naming all your variables x1, x2, x3... might be a good idea for some cases, so not even naming conventions are universal. The idea behind such rules is usually much more universal than the rule itself, but you don&#39;t teach someone the idea by just telling them the rule. For that you need to explain things.
Rules are crutches for the brain to remember the reasons behind them, and you need them just because access to human memory banks is organized in such a weird way http://forums.bistudio.com/oldsmileys/wink_o.gif
In the end every piece of code has its own set of things it needs to achieve and therefor you can&#39;t just apply general rules without knowing their reasoning.
In most of the cases trying to get an average response time of 0.04s from a database is just wasting project resources while most time it&#39;s essential for a game.

To stay with your example of the birds and the nest:
If you just tell them that it&#39;s generally a good idea to flap with the wings, they might as well jump out of the nest thinking they can fly because they&#39;re flapping with their wings, only to crash into the next best thing since they didn&#39;t know anything about steering or landing. The result will be the same: Hurt bones.
I&#39;m not saying to just push them out, but to tell them what it takes to fly. After all they asked about it, so they should be prepared to get the full deal. After that they can still decide if they just want to sit in the nest and practice some flapping, but at least they know then what it takes to get it done.


*are calls like loadFile, exec or execVM cached in ArmA?
Somewhere Kegetys posted that tricks like fwatch don&#39;t work with ArmA. Maybe because file access is cached now?

CrashDome
Dec 14 2006, 20:28
I think we are getting each other wrong somewhere along the lines. I really don&#39;t want to debate anymore, but I will say you are taking things I say a bit too literally (i.e. I never used the word "rules" - I used the term "patterns and practices" - they might mean the same to you, but not to me). When I speak of language, I fully realize C++/C#/Java patterns don&#39;t apply completely to things like Motorola&#39;s Assembly language let alone ArmA/OFP. All I wanted to suggest is that new guys should follow some guidelines to eliminate most of their problems off the bat. MrZigs example fully fits into this situation. As I suggested to him, functions are the way to go in this situation and *hypothetically speaking* had he been using certain practices, he may have still asked the question simply for the sake of learning more. The difference is that without using certain practice behavior he was forced to ask, whereas the new guy who doesn&#39;t want to ask (don&#39;t ask me why someone wouldn&#39;t want to know - but for arguments sake) can use the practice and still result in similarily efficient code. I understand they don&#39;t apply all the time it&#39;s all just a matter of weeding out some bad coding behavior while teaching some fundamentals.

Seriously, you need to relax a bit on your viewpoints. It&#39;s impossible to teach everyone how everything works - especially if such a person is unwilling to learn that much.

Either way you feel about it is fine, but I will continue to preach what I practice.

Romolus
Dec 14 2006, 22:51
@<hidden>:
I&#39;m not trying to teach everyone how everything works, nor do I intend to tell anyone what he&#39;s supposed to do.
I was merely explaining my point of view in something where it seemed that we didn&#39;t agree. The following posts were just to clear things up and I think we clarified what each others point is. That&#39;s all I intended to do http://forums.bistudio.com/oldsmileys/smile_o.gif

Now back to the topic of functions and scripts.

For OFP, I think using a function call would be the right thing to do, if the function is just doing what MrZig showed as an example for the function.
Also using lots of such frequent function calls can give performance problems, because functions are run in one piece and either end or get aborted. Especially if the function does some more things this might become a problem.
Also to me it looks like it&#39;s not the best way to design a function, but then we don&#39;t really know how the real one looks like. It&#39;s just that the sample code suggests that this could be done in a cleaner way (here&#39;s where patterns and practices come into play).


Now for ArmA that might be different again. Especially after the findings about using the sleep command in functions.
To me this suggests that scripts and functions are much closer in how they&#39;re run in ArmA than they were in OFP. At least for the new script type.

ColonelSandersLite
Dec 15 2006, 21:19
Quote[/b] ]If you need a return from a script then you can also give it an array as parameter where the script puts the result(s) in. Since the array is given to the script by reference, you can read out the return values afterwards.

Yep, but it&#39;s has some restrictions. For example, you can&#39;t use + or - on _resultArray, otherwise you loose your pointer to it.

Actually, there&#39;s a very simple way around that, just go multidimensional.

myArray = [[val1, val2, val3, val4]]

To add a value inside a script which has been passed this array:
_passedArray set [0, _passedArray select 0 + [val5]]

The result:
[[val1, val2, val3, val4, val5]]

To call a specific value from this result:
val = (myArray select 0) select X

UNN
Dec 15 2006, 23:21
I know about multi dimensional array pointers, I’ve been using them for years.

ATCOpen.sqs:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">_Plane=_This Select 0
_Pointer=_This Select 1

;If it&#39;s already opening or closing wait
#L

~1

If &#40;&#40;_Plane animationphase &#34;mtydoor&#34; &#60; 1&#41; And &#40;_Plane animationphase &#34;mtydoor&#34; &#62; 0&#41;&#41; Then {goto &#34;L&#34;}

;If it&#39;s open then skip to the end
If &#40;_Plane animationphase &#34;mtydoor&#34;==1&#41; Then {goto &#34;Exit&#34;}

_Plane animate &#91;&#34;mtydoor&#34;,1&#93;

~5

#Exit

&#40;_Pointer Select 0&#41; Set &#91;0,True&#93;[/QUOTE]

_Pointer is a simple array of [[False]]. Used to handle animation lengths of varying degrees. Although it&#39;s redundant now, as Arma allows you to detect the end of another script.

Your correct in the example you provided, although if val5 was an array that was being pointed to from elsewhere, you would loose that pointer. BTW if you haven&#39;t tried it already. If want to subtract a value and maintain the pointer, you can use:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">&#40;_passedArray Select 0&#41; set &#91;5,&#34;DELETE&#34;&#93;

_passedArray set &#91;0, &#40;_passedArray select 0&#41;-&#91;&#34;DELETE&#34;&#93;&#93;[/QUOTE]

But that wasn&#39;t the example Romulus posted and even then, the topic was about functions and scripts, not array pointers. Plus, I have to restrain myself when it comes to array pointers. They were a rarely used feature in OFP, so it&#39;s great to see them getting the usage they deserve. I’m likely to get carried away…..

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">ARRAY01=&#91;&#91;&#93;,&#91;&#93;&#93;
ARRAY02=&#91;&#91;&#93;,&#91;&#93;&#93;

ARRAY01 Set &#91;0,ARRAY02&#93;
ARRAY02 Set &#91;0,ARRAY01&#93;[/QUOTE]

Edit:

Sorry Romulus, I forgot to mention:


Quote[/b] ]are calls like loadFile, exec or execVM cached in ArmA?
Somewhere Kegetys posted that tricks like fwatch don&#39;t work with ArmA. Maybe because file access is cached now?

Looks that way, although you can force it with loadfile (http://community.bistudio.com/wiki/loadFile). But you have to get the timing right, if you don&#39;t delay the calling loop, you will get a shared file violation.

If fwatch can wait until the file is released? Then the delay could be kept to a minimum.

ColonelSandersLite
Dec 16 2006, 02:15
I know about multi dimensional array pointers, I’ve been using them for years.

I had assumed you knew that. I was just pointing out, for the benefit of anybody who didn&#39;t, that there is a workaround. Mostly to illustrate the point that any limitations can be worked around with proper coding practices and a little creative thought.


Your correct in the example you provided, although if val5 was an array that was being pointed to from elsewhere, you would loose that pointer.

1st, making the assumptions that argument requires, you shouldn&#39;t lose anything, In my example, I wasn&#39;t modifying the array containing val5 at all.

2nd, val5 was a value inside of an array, not an array. Therefore, there&#39;s no such pointer, regardless of the contents of val5. In practicality, val5 is a placeholder that I used for example purposes, and not a global variable. It would be something like _myUnit, or _myPos, or whatever in a real script.

Igor Drukov
Dec 16 2006, 13:51
Hello



The following message is about issuing the command "sleep" in preprocessed .sqf functions. It is the result of various experiments I carried out and what I have found may be wrong. Any con-/in- firmation is welcome.

<ul> Results


"Sleep" works in preprocessed .sqf functions if those functions are called from other not preprocessed .sqf. Not if they&#39;re called from either an .sqs or a trigger or a preprocessed .sqf.

Testing Methods

I created a preprocessed .sqf called "test".
<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">sleep 1;hint &#34;hehe&#34;[/QUOTE]


In the init file:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">SpawnBuild=compile preprocessfile &#34;SpawnBuild.sqf&#34;;sleep 1;&#91;&#93; call test[/QUOTE]

As you may know, init files can be indifferently .sqf or .sqs.

If it&#39;s an .sqf, the hint is displayed. If it&#39;s an .sqs, the hint is displayed, but with an error message (the "error in general expression" one).
A radio trigger with "[] call test" in its activation field always resulted in the same error message.

To confirm these first results, i created a test0 file containing the following line:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">&#91;&#93; call test[/QUOTE]

I made it a non-preprocessed .sqf, and typed <table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">blabla=&#91;&#93; execVM &#34;test0.sqf&#34;[/QUOTE]in the activation field of my trigger.

No error message, the hint appeared.

I then changed test0 to an .sqs, changing the activation field of my trigger accordingly:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">&#91;&#93; exec &#34;test0.sqs&#34;[/QUOTE]

The hint was diplayed, but with the same error message.


I also created another test1.sqf that I preprocessed with "[] call test" in it. You then get the error message too.

Summary (TO BE CONFIRMED&#33; )

<ul> "Sleep" in non-preprocessed .sqf always works;
it will even work in preprocessed .sqf when those .sqf are called from other non preprocessed.sqf;
"sleep" will work in preprocessed .sqf if that .sqf is called from either a trigger or an .sqs or another preprocessed .sqf, but it&#39;ll cost you an error message - and a freezing game for a while on some occurrences.[/list][/list]


Hopefully this is of some kind of interest, if only because the distinction between preprocessed .sqf and not preprocessed .sqf seems to be extremely important.

But once again, please someone confirm this&#33;



Regards,




Igor.

rwillis
Dec 16 2006, 19:29
So should we only use .sqf files now (instead of the old .sqs ones)?

ColonelSandersLite
Dec 16 2006, 22:02
So should we only use .sqf files now (instead of the old .sqs ones)?

That&#39;s what the biki says. Although there is some inconsistancys, it&#39;s pretty consistant about that.

It says pretty explicitly that the old sqs format is depreciated now which is generally understood to mean that it&#39;s strictly there to enable old stuff to run. Usually, it also means that it&#39;s unsupported, and won&#39;t be around in future versions.

For your convienince, here&#39;s a script I wrote in ofp that I have just converted to ARMA:

bring_out_your_dead.sqs
<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">; removes the body after the specified number of seconds passed
; in this case, 5 mins
_removeBodyAfterTime = 300

; should be the unit that you called this script on
_unitToRemoveWhenDead = _this select 0

; circles till the guy dies&#59;&#41;
; pretty coarse detection here, no need to be too precise
#vultureLoop
~15
? alive _unitToRemoveWhenDead &#58; goto &#34;vultureLoop&#34;

; wait the specified amount of time to mop up
~_removeBodyAfterTime

&#91;_unitToRemoveWhenDead&#93; join grpNull
deleteVehicle _unitToRemoveWhenDead
[/QUOTE]

CSL_Bring_Out_Your_Dead.sqf (arma script, used by execVM)
<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">// set variable scope
private &#91;&#34;_removeBodyAfterTime&#34;, &#34;_unitToRemoveWhenDead&#34;&#93;;

// should be the unit that you called this script on
_unitToRemoveWhenDead = _this select 0;

// removes the body after the specified number of seconds have passed
// in this case, 5 mins
_removeBodyAfterTime = 300;

// waits till the guy is dead. Pretty coarse detection, we don&#39;t need fine precision here.
while {alive _unitToRemoveWhenDead} do
{
sleep 30;
};

// wait the specified amount of time to mop up
sleep _removeBodyAfterTime;

// hideBody makes the body sink into the ground
hideBody _unitToRemoveWhenDead;

// wait a few secs for the body to be hidden
sleep 10;

// remove the body permanently
deleteVehicle _unitToRemoveWhenDead;[/QUOTE]

Looking above, you can see that the conversion is pretty easy once you understand the function structure.

I have to say thank god we no longer have to use gotos to simulate loops and case structures and stuff...

rwillis
Dec 16 2006, 23:22
Thanks&#33;  This is what we need more of in the biki...  more examples.

So that checks every 30 seconds to see if that unit died?

UNN
Dec 17 2006, 00:04
@<hidden> Drukov

Take a look at the preprocessFile (http://community.bistudio.com/wiki/preprocessFile) in the wiki. The command does not effect how each command is called, just how it&#39;s formatted before calling.

Putting that aside, I tested the same batch of commands:

you can call any of the following from within a script using execVM (http://community.bistudio.com/wiki/execVM), without any errors and expect to see the correct output:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">Call Compile &#34;Sleep 5; Player SideChat Format &#91;&#34;&#34;1st Sleep Time %1&#34;&#34;,Time&#93;; Sleep 5; Player SideChat Format &#91;&#34;&#34;2nd Sleep Time %1&#34;&#34;,Time&#93;; Sleep 5; False&#34;[/QUOTE]

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">Call Compile LoadFile &#34;SleepTest01.sqf&#34;;[/QUOTE]

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">Call Compile PreProcessFile &#34;SleepTest01.sqf&#34;;[/QUOTE]

Where the file SleepTest01.sqf contains this:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">Sleep 5;

Player SideChat Format &#91;&#34;1st Sleep Time %1&#34;,Time&#93;;

Sleep 5;

Player SideChat Format &#91;&#34;2nd Sleep Time %1&#34;,Time&#93;;

Sleep 5;

False[/QUOTE]

Now if you move any of the above lines into the init field of a unit, you get the following error:


Quote[/b] ]Error Generic error in expression

If you move the same code into a trigger and call it, you get the same error. In both cases, both the sidechat commands are executed, only without the delay from sleep (http://community.bistudio.com/wiki/sleep). The reason you don&#39;t see the sidechat output if run from the init field is, sidechat is executed before the screen initialises during the missions startup.

Just to test the point, I created another function called SleepTestInit.sqf, containing the follwoing line:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">Call Compile PreProcessFile &#34;SleepTest01.sqf&#34;;[/QUOTE]

SleepTestInit.sqf was called from a script using execVM (http://community.bistudio.com/wiki/execVM):

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">Call Compile PreProcessFile &#34;SleepTestInit.sqf&#34;;[/QUOTE]

Again, everything worked as expected.

As a final test, I added this line to the init field of a unit:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">Sleep01=Compile LoadFile &#34;SleepTest01.sqf&#34;; Spawn01=&#91;&#93; Spawn Sleep01[/QUOTE]

This worked as expected, with the sleep (http://community.bistudio.com/wiki/sleep) commands and sidechat providing the correct output.

The conclusions I came to from this are quite complex. Complex enough at least, for me to have to think carefully about how they should be explained. The way I see it, it&#39;s all down to the scope of a script. Scripts have parent scopes, so sleep (http://community.bistudio.com/wiki/sleep) works with the call (http://community.bistudio.com/wiki/call_code) command, from within a script or function that inherits from that parent scope.

The init fields and triggers don&#39;t have a parent scopes, so you can&#39;t use sleep (http://community.bistudio.com/wiki/sleep) with the call (http://community.bistudio.com/wiki/call_code) command.

However, if you use the Spawn (http://community.bistudio.com/wiki/spawn) command from and init field or trigger, you do create a parent scope allowing you to use sleep directly from an init field e.t.c

Ok, that&#39;s probably not very clear. But I think it would take more than an hour or so to formulate a proper explanation of what I think scope is, before I could beging on the commands themselves. Plus anyone just starting out in scripting, should be strongly advised, not to read it.

In short, as far as beginners are concerned, they should be told they can&#39;t use the sleep (http://community.bistudio.com/wiki/sleep) command with the call (http://community.bistudio.com/wiki/call_code) command. If anyone does want to use call (http://community.bistudio.com/wiki/call_code) and sleep (http://community.bistudio.com/wiki/sleep) together (I can think of only one reason to do so, that would probably work) then you should be discreet about it http://forums.bistudio.com/oldsmileys/smile_o.gif

BTW: The same thing applies to theWaituntil (http://community.bistudio.com/wiki/waitUntil) command to.

ColonelSandersLite
Dec 17 2006, 05:27
Thanks&#33; This is what we need more of in the biki... more examples.

So that checks every 30 seconds to see if that unit died?
Yes, and if he has, wait the specified amount of time to remove the body.

I generally disagree about examples in the biki though, unless a special section is added for them.

Others may disagree, but I feel that the biki should be considered more of a community manual, which talks straight facts. Soon enough, we&#39;ll have plenty of examples all over ofpec and these boards.

Actually, I&#39;d like to hear peoples opinions on that subject. I wonder if I&#39;m alone in that school of thought, or if it&#39;s more of a general unspoken consencus.

Igor Drukov
Dec 17 2006, 09:44
Take a look at the preprocessFile in the wiki. The command does not effect how each command is called, just how it&#39;s formatted before calling.


Well, this is confusing because I&#39;ve never implied such a thing.

The more general issue I am raising is that apparently the same lines of codes and the same functions will or will not work depending on where they are called from. That is what my original message amounted to.

And if I&#39;m not mistaken you are saying exactly what I say too.

Now I think a WAY stricter definition of what a function and what a script are needs to be made. It came to mind after reading your tests with the "spawn" commands in a unit&#39;s init line.

If you take a look at the Spawn (http://community.bistudio.com/wiki/spawn) command, you will have noticed the description says:


Quote[/b] ]The new script (Function) is running in parallel, spawn does not wait for it to be done


This is extremely important&#33; Here is how I see things - I&#39;ll be trying to be as simple as I can, I hate jargon.

But first, a little terminology.
I would personnally be in favour of restricting the use of "functions" to lines of code which, when executed, "halt all other game engine processes until they have completed their instructions" (from the Biki (http://community.bistudio.com/wiki/Function)).And to my knowledge, this is only possible with preprocessed/loadfiled .sqf files executed with "call" (and no other command&#33; ).
For obvious reasons, a preprocessed file containing the "sleep" command, even though it is executed with "call", will behave as a script, and so should not be called a function.

All the rest, strictly speaking, is a script.

Now I think a useful way of imagining ArmA&#39;s coding environment is to imagine a gradient, with .sqs on one end and .sqf on the other.

<---------------------------------------------------------&#62;
.sqs .sqf

From there, a few things must be borne in mind:

<ul> The editor is an .sqs environment.
the behaviour of a script pertains to the environment it has been called from.
certain commands belong to one end of the gradient EXCLUSIVELY ("exec" for .sqs, "sleep" for .sqf for instance).
other commands port one behaviour from one end to the other ("spawn" allows .sqf behaviour from an .sqs environment).[/list]

All this -I think&#33;- rather clearly explains the strange behaviour of "sleep" in certain circumstances.

At least, that&#39;s the way I see it all... I hope you will find it useful too&#33;




Regards,



Igor.

UNN
Dec 17 2006, 15:35
Quote[/b] ]Well, this is confusing because I&#39;ve never implied such a thing.

Oh, sorry. I thought this line was pretty explicit though?


Quote[/b] ]the distinction between preprocessed .sqf and not preprocessed .sqf seems to be extremely important.

Considering we are talking about the sleep (http://community.bistudio.com/wiki/sleep) command, that was certainly the way I read it.


Quote[/b] ]And if I&#39;m not mistaken you are saying exactly what I say too.

Yep, I even said it a few post back from that to. It was just confusing when you talk about preprocessing the file at the same time. As the sleep (http://community.bistudio.com/wiki/sleep) command acts the same way, regardless. But as long as it&#39;s made clear, then it will save a load or problems for people later on. So it&#39;s not necessarily a bad thing, to keep re-iterating it.


Quote[/b] ]The editor is an .sqs environment.

Yeah, kind of. At least the init fields and trigger conditions e.t.c are. Although it&#39;s limited, sleep (http://community.bistudio.com/wiki/sleep) and waitUntil (http://community.bistudio.com/wiki/waitUntil) being some examples and local variables, another.

Igor Drukov
Dec 17 2006, 17:23
Hum.
I won&#39;t be nit-picking about how absurd it is to make entailments (http://en.wikipedia.org/wiki/Entailment#Semantic_Implication) from hedged utterances (http://exchanges.state.gov/EDUCATION/ENGTEACHING/pubs/BR/functionalsec3_8.htm) or to confuse implicit and explicit, since we agree and since it wouldn&#39;t serve the general purpose of this thread.

Still, what I could read about nowhere (and this doesn&#39;t mean it doesn&#39;t exist) is how where a given code is executed from affects its execution. Once again, exactly the same lines of codes executed from different environments will or will not produce error messages.

Also, I truly believe the term "function" should be reserved exclusively for time-halting files, i.e. preprocessed files, executed with call, and not containing any time-related variables such as "sleep" or "waitUntil".

Anyway, I&#39;m off to listen to Stevie Wonder&#39;s Innervisions - it&#39;s got some appropriate songs in it.

Regards,



Igor.

UNN
Dec 17 2006, 19:23
Quote[/b] ]where a given code is executed from affects its execution

Second page of this thread, ninth post down.


Quote[/b] ]I tried to execute the same function from an objects init field, that didn&#39;t work. The sleep keeps throwing up an error. From a script it&#39;s ok.

But it&#39;s not like I went into any detail and it&#39;s a crude explanation on my part. So there is no harm in us expanding on it.

If by preprocessed file you mean:

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">MyFunc=Compile PreProcess &#34;Function.sqf&#34;;

Call MyFunc;[/QUOTE]

Then yeah, as a basic rule, it works for me&#33; I&#39;ve yet to check if you can now load a function from an addon, using preprocessFile (http://community.bistudio.com/wiki/preprocessFile). But assuming there is no major over head, then why not? If your not using C(++) syntax or comments, then sometimes there are better alternatives,  that don&#39;t use preprocessFile (http://community.bistudio.com/wiki/preprocessFile). But work exactly the same as any other functions. But that’s best left for other topics.


Quote[/b] ]Anyway, I&#39;m off to listen to Stevie Wonder&#39;s Innervisions - it&#39;s got some appropriate songs in it.

Well as long as doesn&#39;t harm anyone...permanently. Then I guess, even listening to Stevie Wonder can be forgiven http://forums.bistudio.com/oldsmileys/smile_o.gif

Regards

CrashDome
Dec 18 2006, 18:18
Before you guys debate any further. Can anyone confirm that functions (using preprocessfile and call command from within an sqs file or init line) still halt the engine code? OR stop executing after 10,000 loops (or whatever that number was)?

We&#39;ve all made that assumption that nothing in that department has changed from OFP, but I am getting a theory that they in fact do not do that anymore.

I honestly am starting to think that this is much simpler than we think. My new theory is that the function parsing/compiling engine has simply been updated to accomodate parallel execution and unlimited looping. So basically it is the same as OFP sqs only with different syntax and capability (return values and better efficiency).

I only base this theory on the idea that no one has confirmed halting of code via a called function which IMO is the only thing that seperates SQF Functions from SQF "Scripts". If we eliminate that seperation it all becomes very clear to me.

Igor Drukov
Dec 18 2006, 18:57
Well preprocessing a function with:<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">private &#91;&#34;_i&#34;&#93;;
_i=0;
while {_i&#60;11000} do {_i=_i+1};
hint format &#91;&#34;%1&#34;,_i&#93;;[/QUOTE]
returns 10,000.

As to whether they halt the engine, my guess would be yes after observing a slight freeze for heavy functions. But I can&#39;t think of a reliable way to prove it.





Not preprocessing the file and execVM it also returns 10,000.

CrashDome
Dec 18 2006, 20:06
OK, in light of this confirmation, I am doing a 180 and going to develop a different theory of how this engine is designed.

IMO, there is definately a few different environments - probably based on class type. Triggers and Init fields are properties of a class. When you "exec", "execVM", or "spawn" something you are calling directly rather than calling code from a property.

Before I confuse anyone further, I am going to try and figure this out (with help of course&#33; - thanks Igor).

ColonelSandersLite
Dec 19 2006, 07:25
I&#39;m not 100% positive, but I think that execVM also stops engine execution until it either finishes, hits a sleep command, or has to output something.

I noticed this when I accidently made an infinite loop. I didn&#39;t think to test it further, but immediatly fixed it.

Now that I think of that, I need to test that out.

If I&#39;m correct on that, it would mean that the only difference between an sqf script and an sqf function is wether or not they return a value, and potentially, the results of a sleep command.

Now, I&#39;ve just got to think of a clevar **** way to do that test reliably.

CrashDome
Dec 19 2006, 13:59
I&#39;m not 100% positive, but I think that execVM also stops engine execution until it either finishes, hits a sleep command, or has to output something.

I noticed this when I accidently made an infinite loop.  I didn&#39;t think to test it further, but immediatly fixed it.

Now that I think of that, I need to test that out.

If I&#39;m correct on that, it would mean that the only difference between an sqf script and an sqf function is wether or not they return a value, and potentially, the results of a sleep command.

Now, I&#39;ve just got to think of a clevar **** way to do that test reliably.
Igor ran some tests for me last night. We&#39;ve decided that the sleep command hs zero input on parallel execution. It will certainly halt a function called with &#39;call&#39; but the script which called it is also in a state of suspension. The only method to halt the engine is with &#39;call&#39; and even with the sleep or waituntil command the engine may continue but the original script is waiting for that function to finish, thus the original Script is still halted. However, execVM and spawn do not halt any code so anything is run parallel - let me explain:

Script A (SQS with exec or SQF with execVM or spawn) executes and you reach a point where Function A is called (via call command). Script A is halted as is the engine until call returns a value. If the Function should implement the sleep or waituntil command, Script A remains halted waiting for the call command to finish but the engine continues. Once sleep or waituntil is over, the function continues and halts the engine again.

If we take the same story but instead of Function A - we replace it with Script B (same text file executed with compile command and spawn) then the two scripts run in parallel. Script A *may* finish before Script B. This is why you need to use the scriptDone command to make sure the script is complete if you want to wait for it in Script A. ExecVM seems to produce the same behavior *except* that it also compiles the code and eliminates the need for compile or such before spawn. The drawback to that is if you loop your script and call Script B multiple times, you are better off compiling before the loop and spawning it as needed.

ColonelSandersLite
Dec 19 2006, 15:08
You know, I knew all of that (well, 99% of it), and looking back, I have no clue what the hell I was thinking when I wrote that. I&#39;m just going to chalk it up to being tired and my mind on something else.

I made a few bonehead moves last night, so that post isn&#39;t the only thing...

Igor Drukov
Dec 19 2006, 16:46
Igor ran some tests for me last night. We&#39;ve decided that the sleep command hs zero input on parallel execution. It will certainly halt a function called with &#39;call&#39; but the script which called it is also in a state of suspension. The only method to halt the engine is with &#39;call&#39; and even with the sleep or waituntil command the engine may continue but the original script is waiting for that function to finish, thus the original Script is still halted. However, execVM and spawn do not halt any code so anything is run parallel.


Here is the method implemented:

<ul> a script called caller.sqf:
<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">private &#91;&#34;_i&#34;&#93;;
_i=0;

while {_i &#60; 10} do {_i=_i+1;&#91;&#93; call counter};

hint format &#91;&#34;%1&#34;,Global_Var&#93;[/QUOTE]
a preprocessed counter.sqf:
<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">private &#91;&#34;_i&#34;&#93;;
_i=0;
while {_i&#60;10} do {sleep 0.1;Global_Var=Global_Var+1;_i=_i+1};
_i[/QUOTE]
Global_Var set to 0 in the init.sqf[/list]

Executing caller.sqf returns 100 in the hint when counter.sqf is executed with the call command, regardless of whether sleep is used. With ExecVM and spawn, 0 is returned.

CrashDome
Dec 19 2006, 17:17
Seriously, the biki is getting me really pissed off.

twice now I&#39;ve lost pages of material when editing. I guess I am going to have to go one step further and use notepad ahead of time.

This is why Web-based office document editing will never take off...

Anyways, expect some detailed information and some diagrams by tomorrow on the biki. I have to rewrite a few pages because seperating the topics into scripts vs functions is bad. It should have been SQS vs SQF and discuss scripts/functions within each - not that anyone could have known back then.

.kju [PvPscene]
Dec 19 2006, 20:22
keep up CD http://forums.bistudio.com/oldsmileys/smile_o.gif

the internet will "never" work without notepad http://forums.bistudio.com/oldsmileys/whistle.gif

ColonelSandersLite
Dec 19 2006, 22:24
Seriously, the biki is getting me really pissed off.

twice now I&#39;ve lost pages of material when editing. I guess I am going to have to go one step further and use notepad ahead of time.
Can&#39;t be as bad as the ofpec you&#39;ve already submitted this post bug.

Mr.Peanut
Dec 20 2006, 14:59
LOL. I commented on all this way back in September and predicted this chaos. Check the discussion on the Biki Talk:Function page (http://community.bistudio.com/wiki/Talk:Function). I also suggested that the best solution would be the adoption of a new file extension for SQF syntax scripts: SQP or SQFP to indicate they run in parallel. Unfortunately, nobody was listening.

CrashDome
Dec 20 2006, 15:37
LOL. I commented on all this way back in September and predicted this chaos. Check the discussion on the Biki Talk:Function page (http://community.bistudio.com/wiki/Talk:Function). I also suggested that the best solution would be the adoption of a new file extension for SQF syntax scripts: SQP or SQFP to indicate they run in parallel. Unfortunately, nobody was listening.
hehe.. yes I read that. Which is what prompted me to step in a bit. I have what I believe is a much more effective explanation for not only newcomers, but also for veterans.

Of course it wouldn&#39;t be complete without a few diagrams http://forums.bistudio.com/oldsmileys/wink_o.gif

whisper
Dec 20 2006, 15:55
keep up CD http://forums.bistudio.com/oldsmileys/smile_o.gif

the internet will "never" work without notepad http://forums.bistudio.com/oldsmileys/whistle.gif
Correction : The Internet will never work without vi. http://forums.bistudio.com/oldsmileys/wink_o.gif

CrashDome
Dec 20 2006, 17:23
I&#39;ve redone some pages:

SQF (http://community.bistudio.com/wiki/sqf_syntax)

and

SQS (http://community.bistudio.com/wiki/sqs_syntax)

Please note also re-did the function page. I was going to merge it with SQF and realized it really does deserve it&#39;s own page.

[EDIT] Having done all this research and seen Suma&#39;s comments in various areas of the biki, I can see how it has become over-complicated by the community. We really don&#39;t need SQFP or SQP or any other new file extension. Truth is SQS = line-by-line
SQF = C-style

The only thing that makes a function is the call command. As a result of using the call command, you can only use SQf syntax. We as a community, however, have somehow seperated SQF scripts from SQF functions from SQS scripts, etc.. etc.. more than we needed to.

UNN
Dec 20 2006, 19:45
Quote[/b] ]The only thing that makes a function is the call command.

At this point, the only thing I would say is set in stone, when it comes to functions is:

They can return a variable of type Any.

But, isn&#39;t how the call command interacts with the clock cycle still up for debate? Obviously the sleep command, narrows the gap. But I&#39;ve yet to see anything that says commands executed with call (http://community.bistudio.com/wiki/call_code), behave in exactly the same way as if they were executed with Spawn (http://community.bistudio.com/wiki/spawn)?

Or, did you find otherwise?

Edit:

If your thinking along the lines of simplicity, then yes. But even then, the ability to return a variable, before some significant event / decision. Is still quite important?

CrashDome
Dec 20 2006, 19:59
I guess that is where I have learned something new myself... it all rests on *literally* the call command. The code appears to be the same and appears to execute the same regardless of function or script (execVM or spawn). The reason there is a variable returned is because the functionality of the call command. Call is expected to return a result and it takes the last expression of the SQF code without a ; as that result. Which is why we can end with a ; and there is no result. If we take a function file (SQF file without a final ; ) and spawn it, it will produce the same results only parallel in execution. It *may* error on the last expression... perhaps someone with ArmA can verify... but the only reason it would error out IMO is because compile/spawn or execVM are trained to look for that final &#39;;&#39;.

By nature, the file or syntax does not return a result. Only the call command expects this additional behavior and therefore we call it a "function" instead of a "script" even though commands and base behavior is the same.

UNN
Dec 20 2006, 20:07
Quote[/b] ]The code appears to be the same and appears to execute the same regardless of function or script (execVM or spawn).

I know I haven&#39;t done this myself, which was why I asked in the first place. But what size functions were you calling?

CrashDome
Dec 20 2006, 20:33
From what I recall (Igor did the tests at my request), they were short functions/scripts which produced 9000+ loops which incremented an integer by 1.

At the time, our biggest concern was timing them to determine if the engine was halted versus mission time resumed as normal.

None of them produced any error despite which way they were executed.

Now, in regards to your problem with Trigger fields and Init lines, I think the problem is merely how these code blocks are executed. I don&#39;t know if they use call for these internally or if they are run parallel via spawn or such? Are they compiled first? etc.. etc.. best to ask Suma how code-fields of objects are treated (e.g. Init Line, Activation Field, etc..). If he comes back and says they use something different internally than any command we have seen thus far, then atleast we know generally why those act differently - even if we don&#39;t know the specifics.

Keep in mind most of my results were from gathering experiences from Igor, you, Suma&#39;s posts on the wiki, etc...

I&#39;ve made some assumptions, but until someone says otherwise I don&#39;t think they will harm anyone.

UNN
Dec 21 2006, 07:52
Quote[/b] ]We as a community, however, have somehow seperated SQF scripts from SQF functions from SQS scripts, etc.. etc.. more than we needed to.

I agree, but perhaps not for the same reason? The C style syntax being used for everything now, is great. Used with the Compile command, it must reduce the overheads when calling code. I think the problem is, people now think the code executes in a different way than it did with OFP.


Quote[/b] ]I guess that is where I have learned something new myself... it all rests on *literally* the call command. The code appears to be the same and appears to execute the same regardless of function or script (execVM or spawn).

There are a couple of things I can think of that support your viewpoint:

From now on, most loops are going to be using waitUntil (http://community.bistudio.com/wiki/waitUntil), for (http://community.bistudio.com/wiki/for_var) and while (http://community.bistudio.com/wiki/while) e.t.c All of there conditions behave like the call (http://community.bistudio.com/wiki/call_code) command did in OFP. I think waitUntil (http://community.bistudio.com/wiki/waitUntil) is the Arma equivalent to OFP&#39;s @<hidden> command.

Even in OFP, scripts were quite aggressive. If you looped a single script using exec (http://community.bistudio.com/wiki/exec), without a pause, you were likely to lock up the entire game. So it&#39;s not like there is anything inherent within exec (http://community.bistudio.com/wiki/exec), that shares resources. You had to pause the script yourself. So we can assume the same applies to execVM (http://community.bistudio.com/wiki/execVM) and Spawn (http://community.bistudio.com/wiki/spawn).

Add to that, you can now pause code executed with call (http://community.bistudio.com/wiki/call_code).

They all help narrow the gap between the call (http://community.bistudio.com/wiki/call_code) and execVM (http://community.bistudio.com/wiki/execVM) commands. But IMHO there are still enough distinctions left, to stick with specific terminology.

Ok, slightly revised. But this is what I think warrants the term function:

Code that returns a value.
Code that automatically halts the parent script until completed.
Code that executes at specific points (during startup and event handlers).

The last line hasn&#39;t been mentioned yet regarding Arma, plus I haven&#39;t tested this with Arma myself. But in OFP the call (http://community.bistudio.com/wiki/call_code) command allowed you to execute code in a specific order. For example if you used call (http://community.bistudio.com/wiki/call_code) in the init event of an addons config. The code would be executed before any groups were created and also before any other exec (http://community.bistudio.com/wiki/exec) commands. There was a similar condition for MP startup to. This is quite handy if you need to prepare variables e.t.c for the addon, before anyone starts running scripts with it.


Quote[/b] ]If he comes back and says they use something different internally than any command we have seen thus far, then atleast we know generally why those act differently - even if we don&#39;t know the specifics.

Yep, I will take things on face value in the absence of any other information. I think execVM (http://community.bistudio.com/wiki/execVM) is just a modified version exec (http://community.bistudio.com/wiki/exec), to support C++ syntax and return a script handle. Spawn (http://community.bistudio.com/wiki/spawn) is a modified version of execVM (http://community.bistudio.com/wiki/execVM), to execute pre-compiled code. call (http://community.bistudio.com/wiki/call_code) has been modified to handle pre-compiled code to.


Quote[/b] ]Now, in regards to your problem with Trigger fields and Init lines, I think the problem is merely how these code blocks are executed.

I don&#39;t think it&#39;s a big problem. For me it&#39;s no different to, not being able to use local variables in init fields. You just get used to doing without.  But I&#39;m sure it will crop up at some point.

CrashDome
Dec 21 2006, 13:34
You&#39;ve pretty much said what my conclusions were.

The only thing I don&#39;t know is how functions interact with other scripts. I know they pause the parent script, but do others continue to operate during the "sleep" period. I am assuming so.

I don&#39;t agree that execVM is modified exec. Rather, I do think they are completely different. I think compile and spawn are new and developed to mimic exec but use the sqf parsing engine. I think execVM was created merely to make it even easier to call an SQF script (execVM is like calling compile and spawn in same line). By naming it similar to exec, it&#39;s easier to transition to as a coder.
I think call has not changed at all - except for the sleep and waitUntil commands which are huge for us vets but nothing to scream home about for those that never wrote a function in OFP.


Quote[/b] ]They all help narrow the gap between the call and execVM commands. But IMHO there are still enough distinctions left, to stick with specific terminology

Which is why I did not merge Function page in wiki into the SQF page. We also don&#39;t really need a "script" page just because we have "Function" page either. IMO scripts are everything... there is nothing distinct about them from everything else. However, functions are a distinct topic within scripts that merely describe the effects of using call

So other than that, I think we&#39;ve beaten this topic to death http://forums.bistudio.com/oldsmileys/smile_o.gif

I really hope this enlightens those that are confused about functions vs scripts and I REALLY HOPE it persuades those still using SQS to migrate. It really only takes a few hours to learn to code in SQF style if you&#39;ve done SQS. They are more flexible and have far more capabilities. So there isn&#39;t any excuse to stay with SQS anymore.

[EDIT] I see Hardrock has edited my pages and completely rearranged them. I don&#39;t advise the way he&#39;s organized it. (See previous paragraph to explain why). I also don&#39;t like the wording of it. Sections are all over the place. There are more categories than there is information. However, it still works I guess......

[EDIT 2] OK, it&#39;s looking better now.

CrashDome
Dec 22 2006, 16:02
OK, within 48 hours all of my writing and efforts on the wiki have been deleted or replaced. None of it a result of discussion and completely without warning.

I take serious offense to that and just wish to say I will not be doing anymore direct contribution.

deanosbeano
Dec 22 2006, 16:14
hmm ,maybe this a good time to ask, would someone kindly consider , making a none official wiki for scripting ?
i dont do html etc etc. but the biki is a complete and utter shambles( all hardwork respected).

nubbin77
Dec 22 2006, 17:12
Forgive my ignorance of the internet... but anyone can just delete or edit entries on Wiki&#39;s? WTF how does anything important stay unmolested on ANY wiki? I would think that ass clowns would just put crap in for the sake of being ass clowns. http://forums.bistudio.com/oldsmileys/banghead.gif

Planck
Dec 22 2006, 17:16
Quote[/b] ]
OK, within 48 hours all of my writing and efforts on the wiki have been deleted or replaced. None of it a result of discussion and completely without warning.


I think you are mistaken, if you had bothered to search you would have found the SQS (http://community.bistudio.com/wiki/sqs_syntax) and the SQF (http://community.bistudio.com/wiki/sqf_syntax) pages without too much bother.

Nothing whatsoever has been deleted.......think before you say things like that, and at the very least check further.


Planck

CrashDome
Dec 22 2006, 17:33
In their defense, they have mods alot like forum mods to check on changes. The idea of a wiki is a good idea. Someone discovers something new or something changes then any old bloke can make that change in the wiki. The general consensus is that hopefully more good than bad happens. There is also the idea that sometimes talks and discussion are important before any major changes.

For example, my changes for the most part were additions and the pages I made were to correct two dead-in-the-water pages that were no longer necessary. I even warned of impending changes and commented on many. I left most product in tact and barely adjusted any sections to respect the idea that my opinion of how it should look might not be the majority consensus.

The reason I am upset, is for the sole fact that a major change has taken place in which one person had sole discretion and there was no discussion about the changes being made. I believe these changes would have been brought about over time by the community anyways. However, that does not warrant behavior like I saw IMO.

I respect the intentions and the hardwork of the individual, but feel there has been no respect for my hardwork.


Quote[/b] ]I think you are mistaken, if you had bothered to search you would have found the SQS and the SQF pages without too much bother.

Nothing whatsoever has been deleted.......think before you say things like that, and at the very least check further.


Planck

Yes, there have been deletions and if you check history you&#39;ll see that.

[EDIT] OK, by technicality you can say "move" or "replace" interchangably for some of them. However, my point does not change.

[EDIT 2] I apologize to everyone if this has derailed the thread. I think I&#39;ve learned my lesson and will stay away from the wiki. Whether it&#39;s fate or coincidence, everytime I go near that thing it blows up in my face.

On the other hand, is it true that compile will be required in front of preprocessfile before you can successfully call it? e.g....
<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">myFunction = preprocessfile &#34;test.sqf&#34;;
myResult = call compile myFunction;
[/QUOTE]

and can you alternatively do this:
<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">myFunction = compile preprocessfile &#34;test.sqf&#34;;
myResult = call myFunction;[/QUOTE]

anyone have concrete proof of this?

zyklone
Dec 22 2006, 18:52
On the other hand, is it true that compile will be required in front of preprocessfile before you can successfully call it? e.g....
<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">myFunction = preprocessfile &#34;test.sqf&#34;;
myResult = call compile myFunction;


and can you alternatively do this:
<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">myFunction = compile preprocessfile &#34;test.sqf&#34;;
myResult = call myFunction;[/QUOTE]

anyone have concrete proof of this?[/QUOTE]
Yes, you have to run compile first.

The second version of those two is the only one that should be used as otherwise you have to run &#39;compile&#39; each time you want to run the function.

It&#39;s best to do

<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">
myFun = compile preprocessFile &#39;myfun.sqf&#39;;
[/QUOTE]

Once in init.sqf, after that myFun will contain Code. And can be &#39;call&#39;ed without extra processing. If you do &#39;call compile myFunction&#39; all the time you loose much of the added performance since you are just storing a string instead of Code.

Or even worse if you preprocess the file all the time then you&#39;ll be doing much unneeded disk IO.

CrashDome
Dec 22 2006, 19:38
Great. I understand perfectly now.

I will have to watch what say as we all know in OFP it was not necessary.

sbsmac
Dec 22 2006, 22:36
Actually there is another pattern you can use:

File "my library.sqf"
<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">
library_func1={ hint &#34;lib1&#34;&#59;}&#59;
library_func2={ hint &#34;lib2&#34;&#59;}&#59;
[/QUOTE]

then:-
<table border="0" align="center" width="95%" cellpadding="0" cellspacing="0"><tr><td>Code Sample </td></tr><tr><td id="CODE">call compile preprocessFile &#34;my_library.sqf&#34;
call library_func1
call library_func2 [/QUOTE]

Useful for packaging related functions.