Jump to content

Photo
- - - - -

How and when to use spawn vs execVM.


  • Please log in to reply
21 replies to this topic
Thread Starter
Splicer
Splicer

    Sergeant

  • Members
  • 198 posts

  • Joined: 14-December 2009

Posted 06 January 2010 - 15:12 #1

Hi,

I've read in the http://community.bis..._Commands_ArmA2 the info on the commands spawn and execVM.

I understand that execVM is used to call and run a script.

I read somewhere that if a script will be used/called many times it is advisable to compile the script and store/cache it in memory so the engine doesn't have to access the hard drive every time such script is to be run, in turn increasing game efficiency and performance.

I searched in the forum for an example of the use of the spawn command (in layman terms), but I only found threads about spawning units/objects/etc.

I would be extremely grateful if anybody could explain to me how to use the spawn command (vs execVM) with a simple example/case.

Thank you much in advance. Splicer.
"We must either find a way or make one."
- Hannibal

Shuko
Shuko

    Warrant Officer

  • Members
  • 2138 posts

  • Joined: 19-June 2004

Posted 06 January 2010 - 15:37 #2

Spawn and execvm are exactly the same thing. Spawn takes the code directly and execvm takes an external file from it read the code.

If you are going to call a script many times, do this:

myStuff = compile preprocessfile "script.sqf";

Then you can call that script with:

call myStuff

That way the engine doesnt need to read and compile the script each time, as it's already loaded in the myStuff variable.

Thread Starter
Splicer
Splicer

    Sergeant

  • Members
  • 198 posts

  • Joined: 14-December 2009

Posted 06 January 2010 - 15:48 #3

call myStuff


Hi shk,

Thanks much for explaining this to me! :notworthy:

One more question if you don't mind.

If the script needs to be fed with data (e.g., and array such as [value1, value2, etc.], should the data be contained between "call" and "myStuff"?

Or is there another command (instead of "call") that should be used?

Again, thank you so much shk!

Best, Splicer.
"We must either find a way or make one."
- Hannibal

AliMag
AliMag

    Staff Sergeant

  • Members
  • 226 posts

  • Joined: 08-July 2002

Posted 06 January 2010 - 16:08 #4

Hi,

The same way you would call the script:

[parameters list] execVM "script.sqf";

or

[parameters list] call myStuff;

Cheers

Shuko
Shuko

    Warrant Officer

  • Members
  • 2138 posts

  • Joined: 19-June 2004

Posted 06 January 2010 - 16:09 #5

dataReturned = [datagiven1,given2] call myStuff;

Spawn can also be used to execute myStuff. Difference between spawn and call is that spawn starts a new thread, which runs besides the main game thread, thus not interrupting game flow and call in run in the one that it's called from. If call is run on the main thread (init.sqf, triggers, eventhandlers etc), it can not contain any waituntil/sleep etc which would stop the game. Call can sleep if it's used within a child thread (execvm, spawn).

Edited by Shuko, 08 January 2010 - 20:20.


Murklor
Murklor

    First Sergeant

  • Members
  • 831 posts

  • Joined: 13-June 2009

Posted 06 January 2010 - 16:12 #6

Spawn and execvm are exactly the same thing.

Spawn can be used on internal functions. For example, you can have a dozen functions in a single sqf file running dozens instances of these functions using spawn. With execVM and sqf, you'd have a dozen files instead.

The difference between call and spawn is easy: call goes through your code line by line (ie it doesnt continue with what is after call until what is within call is done), spawn make a new instance and continues with what is after spawn in paralell with what is within spawn.

Thread Starter
Splicer
Splicer

    Sergeant

  • Members
  • 198 posts

  • Joined: 14-December 2009

Posted 06 January 2010 - 23:28 #7

Hi guys,

Super! Your explanation/examples make this crystal clear!

THANK YOU SO MUCH!!! :yay:

My best, Splicer.
"We must either find a way or make one."
- Hannibal

sbsmac
sbsmac

    Master Gunnery Sergeant

  • Members
  • 1297 posts

  • Joined: 24-August 2003

Posted 06 January 2010 - 23:34 #8

Spawn can also be used to execute myStuff. Difference between spawn and call is that spawn starts a new thread, which runs besides the main game thread, thus not interrupting game flow. Call on the other hand is run on the main thread, which means it can not contain any waituntil/sleep etc which would stop the game.


This isn't quite correct. Call simply executes the code 'in-line' with the current thread. waituntil/sleep etc are all perfectly possible inside called code as long as the calling context is a thread in its own right and interruptable. Some contexts are not interruptable (event-handlers for example).

Spawn creates a new (and interruptable) thread in its own right.
Author of PVPmissionWizard ArmA2FPSAnalyser AddonChecker and ... squint

Tools homepage

Crosseyed and Painless - a blog about my ArmA2 developments



Zonekiller
Zonekiller

    Gunnery Sergeant

  • Members
  • 494 posts

  • Joined: 20-November 2005

Posted 07 January 2010 - 10:41 #9

a spawned script will run at the same time as the script that spawned it
a script will stop and wait till the called script is finished.

so if you need input into a script use call , if you want something to happen while
your script is running use spawn

ie
script telling unit to goto somewhere , new script telling unit to setdamage to 0 , you would use spawn

script wanting to tell a unit to go somewhere , new script to find that unit you would use call.

i dont know if that will make sence to you if not i can go into more detail...

Thread Starter
Splicer
Splicer

    Sergeant

  • Members
  • 198 posts

  • Joined: 14-December 2009

Posted 08 January 2010 - 04:56 #10

a spawned script will run at the same time as the script that spawned it
a script will stop and wait till the called script is finished.

so if you need input into a script use call , if you want something to happen while
your script is running use spawn

ie
script telling unit to goto somewhere , new script telling unit to setdamage to 0 , you would use spawn

script wanting to tell a unit to go somewhere , new script to find that unit you would use call.

i dont know if that will make sence to you if not i can go into more detail...


Hi ZoneKiller,

If I understand your examples correctly, one could say that spawn is to be used when the output of one of the 2 scripts does not depend on the other script to be done first (i.e., your example #1).

On the other hand, when the input of a script depends on the result of another script (i.e., your example #2), in such case the call command is to be used.

If the above is correct, then it's not clear to me why one couldn't use spawn for example #2. All that would happen is that the script would remain in memory idle until the AI reached its final destination to then be able to obtain its position.

Is this correct?

Thanks. Splicer.
"We must either find a way or make one."
- Hannibal

Zonekiller
Zonekiller

    Gunnery Sergeant

  • Members
  • 494 posts

  • Joined: 20-November 2005

Posted 08 January 2010 - 05:52 #11

well you do understand it almost rig

using call

1st script

_man = _this select 0;

_man move getpos airport;

waituntil {_man distance airport < 100};


_plane = [airport] call maketheplane;
----script will wait here till the script that makes the plane has been finished ------
----if you used spawn the script would not wait and by now would be asking what F#$%i plane----




_man moveindriver _plane;

_man move flytosomewhere;

------------------------------------------------------------------


maketheplane script

_aiprort = _this select 0;

_plane = "A10" createVehicle position _airport;

_plane

----------------------------------------------------------------------

tcp
tcp

    Gunnery Sergeant

  • Members
  • 435 posts

  • Joined: 02-August 2009

Posted 08 January 2010 - 06:51 #12

Did you already read this? http://community.bis...m/wiki/Function

Just one correction Zone: execVM will always spawn a new thread.

Use execVM for general scripts. It creates a seperate thread outside the game's main thread. You can also use execVM again within that script/thread to spawn another thread.

Use call for simple or constantly repeated functions. Usually, you will store the code in a variable (memory) ahead of time if it is high-priority code (rather than reading from file every time). A call can be used in the main game thread, but has the restriction of not using sleep.

Use spawn only when you need to execute code in a parallel thread that doesn't warrant a script of it's own.

deadfast
deadfast

    Moderator

  • 3175 posts

  • Joined: 05-December 2006

Posted 08 January 2010 - 10:15 #13

An important thing to note when using call is that the function cannot be interrupted - you can't you sleep or waitUntil.


_code =
{
hint "1";
sleep 1;
hint "2";
};

call _code; //error

spawn _code; //works fine


sbsmac
sbsmac

    Master Gunnery Sergeant

  • Members
  • 1297 posts

  • Joined: 24-August 2003

Posted 08 January 2010 - 10:23 #14

Deadfast- that isn't strictly correct. The restriction on sleep/waituntil is only present if the original execution context does not allow blocking. (Eg, event-handler, trigger, init-code etc.)

This code is completely legal....

pause={sleep 10;} ;

callingFunction ={
player sidechat format["before pause %1",time] ;
call pause;
player sidechat format["after pause %1",time] ;
} ;

[] spawn { call callingFunction;} ;


Author of PVPmissionWizard ArmA2FPSAnalyser AddonChecker and ... squint

Tools homepage

Crosseyed and Painless - a blog about my ArmA2 developments



Synide
Synide

    Master Gunnery Sergeant

  • Members
  • 1010 posts

  • Joined: 05-March 2007

Posted 08 January 2010 - 11:57 #15

lol, sbsmac... change your example to this...

pause={sleep 10;} ;
 
callingFunction ={
player sidechat format["before pause %1",time] ;
call pause;
player sidechat format["after pause %1",time] ;
};
 
call callingFunction;
 
[] spawn { call callingFunction;} ; 

...and your illustrating the exact same thing Deadfast's post illustrates.

If one sticks with the text from your first post (which was bang on) and Deadfast's code snippet that pretty much illustrates the call, spawn/execVM situation very well don't you think?
Hibernating (indefinitely/permanently/intermittently)... may respond to email, possibly.

sbsmac
sbsmac

    Master Gunnery Sergeant

  • Members
  • 1297 posts

  • Joined: 24-August 2003

Posted 08 January 2010 - 12:25 #16

Synide - I think you are missing the point I was trying to make. :) There is absolutely nothing inherent about 'call' that prevents you using sleep/waituntil inside it. Both deadfasts and your modified code above don't really illustrate anything because if called from a previously spawned context they will both work just fine !

A lot of people seem to think you can't _ever_ put a sleep statement inside a 'called' piece of code (regardless of context) - this just isn't correct.
Author of PVPmissionWizard ArmA2FPSAnalyser AddonChecker and ... squint

Tools homepage

Crosseyed and Painless - a blog about my ArmA2 developments



Synide
Synide

    Master Gunnery Sergeant

  • Members
  • 1010 posts

  • Joined: 05-March 2007

Posted 08 January 2010 - 13:32 #17

thats true... but you are not putting a sleep inside a call... your putting a sleep inside a spawn... it's irrelevant that inside the spawn you happen to be enclosing the sleep additionally within a 'call' piece of code. The salient point is that you HAD to wrap the sleep within a spawned thread context.

As I said, your first post was bang on the money with the description. Your just confusing noobs by adding the extra information.

Edited by Synide, 08 January 2010 - 13:38.

Hibernating (indefinitely/permanently/intermittently)... may respond to email, possibly.

sbsmac
sbsmac

    Master Gunnery Sergeant

  • Members
  • 1297 posts

  • Joined: 24-August 2003

Posted 08 January 2010 - 13:37 #18

..which is precisely why I was pointing out the distinction between context and lexical scope.

There seem to be some people who believe that

pause={sleep 10;} ;
[] spawn {call pause;} ;


is invalid because, quote, "you can't use sleep inside called code"

Edited by sbsmac, 08 January 2010 - 13:40.

Author of PVPmissionWizard ArmA2FPSAnalyser AddonChecker and ... squint

Tools homepage

Crosseyed and Painless - a blog about my ArmA2 developments



Synide
Synide

    Master Gunnery Sergeant

  • Members
  • 1010 posts

  • Joined: 05-March 2007

Posted 08 January 2010 - 13:50 #19

lol, yeah ok fair enough... :thumbsup:
Hibernating (indefinitely/permanently/intermittently)... may respond to email, possibly.

McArcher
McArcher

    Gunnery Sergeant

  • Members
  • 418 posts

  • Joined: 27-February 2005

Posted 08 January 2010 - 14:54 #20

omg, I thought that execVM stores a compiled variant of the script somewhere in engine's cache memory in order not to compile it again..... I was wrong?