Jump to content
Sign in to follow this  
Heeeere's johnny!

Why are people assigning functions to "null" or "0"?

Recommended Posts

I've seen many people doing this, even in some BIKI article comments and even in articles themselves, like this:

null = [] call myfunction;
0 = ["Hello", "World", 42] execVM "someScript.sqf";

I wonder why. If a function does not return anything, I don't have to assign it to anything - simple as that, isn't it? Or did I miss something?

Share this post


Link to post
Share on other sites

execVM returns script handle, by assigning it to a variable you make the whole statement return Nothing

Share this post


Link to post
Share on other sites

But what is the purpose of it? I run execVM all the time without assigning anything if I don't have to wait for it to finish before going on in the script. So what is it good for to assign it to 0 or a dummy variable?

Share this post


Link to post
Share on other sites

It depends on what my function or script does. 9 times out of 10 my function is going to return a value, so I wouldn't ever assign a null variable, I'd assign normal variable. Actually, in my scripts, if my function doesn't return a value I don't usually try to assign it one, I'll just use [] call myFunction;

However, for a script, it's a different story. All of the scripts that I've released to-date are meant to run continuously until the end of the mission. I assign script handles to null because I don't really know of effect of it. I'm not sure if it just destroys the handle, but what I can absolutely be sure of is that running another script and using null again will overwrite the first handle and make the first script impossible to terminate.

Share this post


Link to post
Share on other sites

If you stick your execVM statement last in HandleDamage code for example, if I remember correctly, you will override default damage handling. If you force the statement to return Nothing then it wouldnt happen.

Share this post


Link to post
Share on other sites

In plain sqf it is usually redundant. But in some cases, like init/exec fields of editor-placed objects/waypoints etc. it seems obligatory, or you get an error "type script expected nothing" or like that.

Share this post


Link to post
Share on other sites

Numbers can't be redefined, hence "0". "null = execVM..." is the same as writing "asdf = ...", null isn't defined in the engine per default.

"Nil" is, and is used to terminate variables / make them undefined. However, at least in A2, it was possible to redefine nil which could cause a lot of issues.

The only time I personally use a script handle is in the editor, since it is required if I need to spawn a new thread (this includes execVM).

0 = [] spawn {//code}

  • Like 1

Share this post


Link to post
Share on other sites

0 = [] spawn {/*code*/};   //works
nil = [] spawn {/*code*/}; //error as nil is a reserverd variable (ArmA 3)

But as far as I understand all the above statements:

If I had a script which is waiting for a user input, would it be wise to execVM that script rather than spawning it? Because using execVM, I could use "waitUntil {scriptDone _handle};" while when spawned, I'd need to do a workaround with a public variable I'd need to set "true" when the script is done.

Share this post


Link to post
Share on other sites
But as far as I understand all the above statements:

If I had a script which is waiting for a user input, would it be wise to execVM that script rather than spawning it? Because using execVM, I could use "waitUntil {scriptDone _handle};" while when spawned, I'd need to do a workaround with a public variable I'd need to set "true" when the script is done.

Both return handles and both can use scriptDone or terminate.

These two lines below are the same as far as im aware

_myThread = [] spawn compile loadfile "myScript.sqf";
_myThread = [] execVM "myScript.sqf";

Although you will want to swap loadFile out for preProcess if you have comments.

As for assigning , I dont know why but i nearly always write my spawns out in full both assigning and passing an empty array. Most of the time i will assign a local variable even if its not used, just as a label more than anything so at a quick glance i can see what that thread is for. e.g

_gameOverThread = [] spawn {
while {!gameOver} do {
	if ( blah ) exitWith {
		gameOver = true;
		publicVariable "gameOver";
	};
	sleep 1;
};
};

Is this a bad habbit? I dont know, I presume _gameOverThread is just going to be cleaned up by the garbage if the script its in ends anyway. Will it take up some memory, sure but how many threads am i going to have running, to many threads would be my bigger problem to keep an eye on rather than a byte of storage holding a thread handle.

Edited by Larrow

Share this post


Link to post
Share on other sites
0 = [] spawn {/*code*/};   //works
nil = [] spawn {/*code*/}; //error as nil is a reserverd variable (ArmA 3)

But as far as I understand all the above statements:

If I had a script which is waiting for a user input, would it be wise to execVM that script rather than spawning it? Because using execVM, I could use "waitUntil {scriptDone _handle};" while when spawned, I'd need to do a workaround with a public variable I'd need to set "true" when the script is done.

You can wait for spawned threads aswell. Edit: apparently larrow posted this already

_handle = [] execVM "script.sqf";
// the above is basically just short for:
_handle = [] spawn {_this call compile preProcessFileLineNumbers "script.sqf"};

// we can wait here if we want
waitUntil {scriptDone _handle};

You'd probably want to post some code if you want better replies.

What is this user input? addAction? GUI? Triggers? Most stuff can be event based rather than waiting with a loop

Is this a bad habbit? I dont know, I presume _gameOverThread is just going to be cleaned up by the garbage if the script its in ends anyway. Will it take up some memory, sure but how many threads am i going to have running, to many threads would be my bigger problem to keep an eye on rather than a byte of storage holding a thread handle.

It's a non-issue. The game is already running countless amount of threads from BIS / Mods, presumably.

Edited by cuel

Share this post


Link to post
Share on other sites

You can already (definitely on DEV) use isNull with scripts. There is also new command scriptNull so that you don't have to wait for thread to finish to obtain the value.

https://community.bistudio.com/wiki/isNull

https://community.bistudio.com/wiki/scriptNull

so you can just

[color="#FF8040"][color="#191970"][b]if[/b][/color] [color="#8B3E2F"][b]([/b][/color][color="#191970"][b]isNull[/b][/color] [color="#191970"][b]uiNamespace[/b][/color] [color="#191970"][b]getVariable[/b][/color] [color="#8B3E2F"][b][[/b][/color][color="#7A7A7A"]"myScript"[/color][color="#8B3E2F"][b],[/b][/color] [color="#191970"][b]scriptNull[/b][/color][color="#8B3E2F"][b]][/b][/color][color="#8B3E2F"][b])[/b][/color] [color="#191970"][b]then[/b][/color] [color="#8B3E2F"][b]{[/b][/color]
[color="#191970"][b]uiNamespace[/b][/color] [color="#191970"][b]setVariable[/b][/color] [color="#8B3E2F"][b][[/b][/color][color="#7A7A7A"]"myScript"[/color][color="#8B3E2F"][b],[/b][/color] [color="#1874CD"]_param[/color] [color="#191970"][b]spawn[/b][/color] [color="#8B3E2F"][b]{[/b][/color]
	[color="#006400"][i]//script[/i][/color]
[color="#8B3E2F"][b]}[/b][/color][color="#8B3E2F"][b]][/b][/color][color="#8B3E2F"][b];[/b][/color]
[color="#8B3E2F"][b]}[/b][/color][color="#8B3E2F"][b];[/b][/color][/color]

to make sure you do not spawn another myScript while myScript is still running.

BTW scriptNull is NULL script so it also works with scriptDone

Share this post


Link to post
Share on other sites

As for assigning , I dont know why but i nearly always write my spawns out in full both assigning and passing an empty array. Most of the time i will assign a local variable even if its not used, just as a label more than anything so at a quick glance i can see what that thread is for.

As for the empty array, I do the same just for clean coding purposes. But as for the assigning, I prefer comments as I don't have to worry to run into any problems with them. But that's none of a deal. Everyone can do it as he wants.

You'd probably want to post some code if you want better replies.

What is this user input? addAction? GUI? Triggers? Most stuff can be event based rather than waiting with a loop

I don't have any particular code right away, it was just ment as an example for the question. But for your question, imagine a situation where a script opens a dialog and waits for it to close to continue with the code. Assigning a function to the "OK" button to execute a "prequel script" could of course solve the issue in that simple example, but you get the idea.

Anyway, thanks for all your explanations. I'm glad to have learned something new today. :)

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×