Guest Posted October 15, 2002 1.85 introduces new powerful scripting possibilities through user definable functions. This is implemented through the "call", "loadFile" and the "if-then-else,while-do... etc" functions. What is the big difference between "call" and the old "exec"? -"call" allows you to return a value. This is imperative in creating larger and more complex scripts. Here is a code example of a simple implementation of a fuction that adds two matrices. Thanks goes to Suma for the code. I have only made small adjustments to make it work with the 1.85 release syntax. testm.sqs </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Code Sample </td></tr><tr><td id="CODE"> _matrixA = [ [2,2], [2,2], [2,2],[1,2]] _matrixB = [ [1,1], [1,1], [1,1],[2,3]] _result = [_matrixA, _matrixB] call loadFile "matrixAdd.sqf" titleText[format["Matrix A:%1\nMatrixB:%2\nA+B:%3",_matrixA,_matrixB,_result], "PLAIN",1] <span id='postcolor'> matrixAdd.sqf: </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Code Sample </td></tr><tr><td id="CODE"> comment {    Demonstration of new expression possibilities    Note: this is not a script, this is single expression    Script constructs @,~, ? or goto are not possible here.    Semicolons are strictly required, as end of line has no special meaning    and is considered as normal space character. }; comment {    All this is implemented using new "while", "if" and "call" functions.    They are real functions taking string arguments and executing them.    Brackets {} are very similiar to quotes - expression closed in them    is string expression. }; comment "Declare local variables"; private ["_matrixA","_matrixB","_rows","_cols","_diff","_result","_i","_j"]; _matrixA = _this select 0; _matrixB = _this select 1; _rows = count _matrixA; _cols = count (_matrixA select 0); _result = []; _i = 0; comment "Perform calculation in two while loops"; while "_i<_rows" do {       _j = 0;    _innerRow = [];    while "_j<_cols" do    {       _diff = ((_matrixA select _i) select _j) + ((_matrixB select _i) select _j);       _innerRow set [_j, _diff];       _j =_j + 1;    };       _result set [_i,_innerRow];    _i=_i+1; }; _result <span id='postcolor'> Share this post Link to post Share on other sites
Prospero 1 Posted October 15, 2002 From the new ComRef: "Many languague constructs (including forEach, if, while) use concept of "code strings". Code is passed as string to them and they interpret it as code if they wish. Since 1.85 string constants can be written in two ways: using double quotes (like "Hello") or curled braces (like {a=a+1}). While both ways are currently equivalent and string constant is created, we recommend to use curled braces for code only, as this makes scripts easier to read - moreover future versions of scripting language may precompile code enclosed in curled braces." Precompiling eventually! Suma & BIS - good show! Prospero Share this post Link to post Share on other sites
hovmand 0 Posted October 15, 2002 Could someone explain to us "normals" what this means? Give us a small example of what can be done please. Share this post Link to post Share on other sites
RED 0 Posted October 15, 2002 Basicly it lets you create a function (like adding 2 numbers together), using a function can keep scripts small if you are going to use the same function (adding 2 numbers together for example) For example instead of putting this in your script file, you just call it (like a header file .h in C++) It will keep your scripts neater and a lot easier to read. </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Code Sample </td></tr><tr><td id="CODE"> comment { Demonstration of new expression possibilities Note: this is not a script, this is single expression Script constructs @,~, ? or goto are not possible here. Semicolons are strictly required, as end of line has no special meaning and is considered as normal space character. }; comment { All this is implemented using new "while", "if" and "call" functions. They are real functions taking string arguments and executing them. Brackets {} are very similiar to quotes - expression closed in them is string expression. }; comment "Declare local variables"; private ["_matrixA","_matrixB","_rows","_cols","_diff","_result","_i","_j"]; _matrixA = _this select 0; _matrixB = _this select 1; _rows = count _matrixA; _cols = count (_matrixA select 0); _result = []; _i = 0; comment "Perform calculation in two while loops"; while "_i<_rows" do { _j = 0; _innerRow = []; while "_j<_cols" do { _diff = ((_matrixA select _i) select _j) + ((_matrixB select _i) select _j); _innerRow set [_j, _diff]; _j =_j + 1; }; _result set [_i,_innerRow]; _i=_i+1; }; _result <span id='postcolor'> RED Share this post Link to post Share on other sites
vektorboson 8 Posted October 15, 2002 Yeah, and for even more hardcore-scripters there is preprocessFile instead of loadFile! You may define your own C-like macros in your SQF-files. I've got a sample function pos2grid which converts ofp-position vector [x,y,z] to grid position "Ea64". create a test.sqs with following content: </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Code Sample </td></tr><tr><td id="CODE"> _gridpos = (getpos player) call preprocessFile "pos2grid.sqf" hint format ["%1", _gridpos] <span id='postcolor'> And create pos2grid.sqf: </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Code Sample </td></tr><tr><td id="CODE"> #define DIV(_X, _Y) ((_X / _Y) - (_X / _Y) % 1) #define MOD(_X, _Y) ((_X % _Y) - (_X % _Y) % 1) private ["_a", "_b", "_result", "_big", "_small", "_num", "_g1", "_g2", "_g3", "_g4"]; _a = _this select 0; _b = _this select 1; _big  = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]; _small = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]; _num  = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]; _g1 = DIV(_a, 1280); _g2 = DIV( MOD(_a, 1280), 128); _g3 = DIV(_b, 1280); _g4 = DIV( MOD(_b, 1280), 128); _result = format ["%1%2%3%4", _big select _g1, _small select _g2, _num select _g3, _num select _g4]; _result <span id='postcolor'> You see that even nested macros are allowed! Now place some trigger and execute test.sqs! Now the gridpos of your player should be displayed! Share this post Link to post Share on other sites
Guest Posted October 16, 2002 </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Quote (Hovmand @ Oct. 15 2002,13:42)</td></tr><tr><td id="QUOTE">Could someone explain to us "normals" what this means? Give us a small example of what can be done please. Â <span id='postcolor'> Example: Function that returns the sum of two numbers: sum.sqf: </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Code Sample </td></tr><tr><td id="CODE"> private ["_a","_b","_sum"]; _a = _this select 0; _b = _this select 1; _sum = _a+_b; _sum <span id='postcolor'> And you would call the function like this to get the sum of for example 2 + 3: </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Code Sample </td></tr><tr><td id="CODE"> _sum = [2,3] call loadFile "sum.sqf" <span id='postcolor'> Share this post Link to post Share on other sites
Doolittle 0 Posted October 16, 2002 Why did one of you use preprocessFile and the other use loadFile?! Doolittle Share this post Link to post Share on other sites
Guest Posted October 16, 2002 PreprocessFile allows you to define macros while loadFile expects a clean format. Share this post Link to post Share on other sites
GAMEER_77 0 Posted October 16, 2002 Because in Bigpoppa's example, he's using the preprocess file to use the 'C-like' functionality. The code in his example only works using preprocess, not loadfile. (I'd imagine ) PEACE Share this post Link to post Share on other sites
Prospero 1 Posted October 16, 2002 Any idea which is faster? Prospero Share this post Link to post Share on other sites
suma 8 Posted October 16, 2002 LoadFile is slightly faster, but both of them can be considered slow, as both of them require file access (which is also true for exec). If you really want something to be fast (which is probably not the case of pos2grid, but may be for some other often executed fuctions), do not do: </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Code Sample </td></tr><tr><td id="CODE">_gridpos = (getpos player) call preprocessFile "pos2grid.sqf" hint format ["%1", _gridpos] <span id='postcolor'> Preload content of the file to some global variable instead (once, in init.sqs). </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Code Sample </td></tr><tr><td id="CODE"> GridPosFunction = preprocessFile "pos2grid.sqf" .... _gridpos = (getpos player) call GridPosFunction <span id='postcolor'> This way you will avoid reloading and releasing file at each use of the function (at some memory cost). Share this post Link to post Share on other sites
uiox 0 Posted October 16, 2002 If I do this </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Code Sample </td></tr><tr><td id="CODE"> _result =(_Pos) call loadFile "GridCoord.sqf" <span id='postcolor'> Call execute ONE time and after bugs. If I do this </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Code Sample </td></tr><tr><td id="CODE">_result =[_Pos] call loadFile "GridCoord.sqf"<span id='postcolor'> No bug, why () works one time? And for OFP scripters without knowledge of C, in sqf you can do this : </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Code Sample </td></tr><tr><td id="CODE"> private ["_result","_GrandeLettre","_PetiteLettre","_Chiffre", "_Chiffrestring","_Pos"]; _Pos = _This select 0; _Chiffrestring =""; _result = ""; _GrandeLettre = (((_Pos select 0) - ((_Pos select 0) Mod 1280))/1280);               _PetiteLettre =((((_Pos select 0) Mod 1280)- (((_Pos select 0) Mod 1280)Mod 128))/128);  _Chiffre = (99 - ((_Pos select 1) - ((_Pos select 1) Mod 128))/128);     _Chiffrestring = Format["%1",_Chiffre]; If (_Chiffre < 10) then  {_Chiffrestring = "0" + _Chiffrestring }; If (_Chiffre != 0) then  {nobody globalchat "Bonjour";nobody globalchat "Au revoir" }; _result = (( ArrayMajuscForGrid select _GrandeLettre) + ( ArrayMinusForGrid select _PetiteLettre) +_Chiffrestring); _result<span id='postcolor'> Very near of OFP scripting I think... Share this post Link to post Share on other sites
vektorboson 8 Posted October 16, 2002 @uiox because one time it's an array of array [_pos] and the other it's just an array (_pos) [_pos] = [ [_x, _y, _z] ] (_pos) = [_x, _y, _z] Share this post Link to post Share on other sites
uiox 0 Posted October 16, 2002 OK, So the right syntax is : [] call gridCoordFunction. Share this post Link to post Share on other sites
suma 8 Posted October 16, 2002 </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Quote (uiox @ Oct. 16 2002,13:18)</td></tr><tr><td id="QUOTE">So the right syntax is : [] call gridCoordFunction.<span id='postcolor'> Both syntax is correct. If you will use (_pos) call gridCoordFunction, _this will be _pos. If you will use [_pos] call gridCoordFunction, _this will be [_pos] - make your choice. Share this post Link to post Share on other sites
Prospero 1 Posted October 16, 2002 </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Quote (Suma @ Oct. 16 2002,12:15)</td></tr><tr><td id="QUOTE">LoadFile is slightly faster, but both of them can be considered slow, as both of them require file access (which is also true for exec).<span id='postcolor'> I always suspected this from my empirical tests, but many thanks for confirming it, Suma. That's very helpful. I suspect I am correct in saying that calling scripts from the Drop command also depends on file access, and is therefore similarly relatively slow. Thanks again Suma. Prospero Share this post Link to post Share on other sites
Prospero 1 Posted October 19, 2002 </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Quote (Suma @ Oct. 16 2002,12:15)</td></tr><tr><td id="QUOTE">If you really want something to be fast, [edit] preload content of the file to some global variable instead (once, in init.sqs). </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Code Sample </td></tr><tr><td id="CODE"> GridPosFunction = preprocessFile "pos2grid.sqf" .... _gridpos = (getpos player) call GridPosFunction <span id='postcolor'> This way you will avoid reloading and releasing file at each use of the function (at some memory cost).<span id='postcolor'> Could I somehow preload a Drop command into a global variable this way? Prospero Share this post Link to post Share on other sites
Doolittle 0 Posted October 22, 2002 Umm, you can't use #define's in a loadFile?? I'm getting |x|#define FOO ... when I load the function. I suppose this makes sense (use preprocessfile instead???), but there's no #ifndef #endif stuff. Maybe this has already been mentioned?? #define does not work with any function you call with loadFile. Doolittle Share this post Link to post Share on other sites
suma 8 Posted October 22, 2002 </span><table border="0" align="center" width="95%" cellpadding="3" cellspacing="1"><tr><td>Quote (Doolittle @ Oct. 22 2002,09:56)</td></tr><tr><td id="QUOTE">#define does not work with any function you call with loadFile.<span id='postcolor'> #define works with text files (including functions) loaded by preprocessFile. Share this post Link to post Share on other sites
svrec 0 Posted November 10, 2002 I have question about command private ["_i","_j","_k"]. What that it function?For example,if I delete this function in pos2grid.sqf(see above),this script been work too. I'm sorry!I not programmer but I want understand this. Can Your cite example were this function it is necessary. p.s.sorry for my english. Share this post Link to post Share on other sites