Home   Help Search Login Register  

Author Topic: Local Variables with EH  (Read 983 times)

0 Members and 1 Guest are viewing this topic.

Lean Bear

  • Guest
Local Variables with EH
« on: 23 Oct 2005, 19:00:23 »
I was wondering if local variables don't work with event handlers.

Example:

_unit addEventHandler ["killed", {_unitDead = true}]

Wouldn't seem to work, but if I use a global variable - everything's ok :-\

Offline Baddo

  • Former Staff
  • ****
  • Reservist Jaeger
Re:Local Variables with EH
« Reply #1 on: 23 Oct 2005, 19:23:59 »
Yes, you need to use global variables with event handlers if you want the variables to be accessible from outside the event handler's code block.

In your example code you are initializing a local variable inside a code block (a block is started with { and ended with } ) and your variable IS alive, but only in that specific code block and you can't access it from anywhere else.
« Last Edit: 23 Oct 2005, 19:27:34 by Baddo »

Lean Bear

  • Guest
Re:Local Variables with EH
« Reply #2 on: 23 Oct 2005, 19:29:00 »
So you're saying that if I was then to do:

_unitDead = false

player addEventHandler ["killed", {_unitDead = true}]

?(_unitDead) : goto "Label"


That wouldn't work at all, right?

Offline Baddo

  • Former Staff
  • ****
  • Reservist Jaeger
Re:Local Variables with EH
« Reply #3 on: 23 Oct 2005, 19:35:46 »
That wouldn't work.

The code block in an addEventHandler command is not local to your script, it is local to the event handler only. So in the code example you just wrote, you have actually two _unitDead variables: the other is in the scope of your script file, and the other is in the scope of the event handler.

The scope I'm talking about is the "space" where your variable exists. A code block is one scope.

Lean Bear

  • Guest
Re:Local Variables with EH
« Reply #4 on: 23 Oct 2005, 19:37:28 »
OK, thanks - I just wanted to be sure :)

Offline Baddo

  • Former Staff
  • ****
  • Reservist Jaeger
Re:Local Variables with EH
« Reply #5 on: 23 Oct 2005, 19:53:54 »
:)

Let me tell you a bit more about this "scope" I was talking about:

Have a look at the following example function:

Code: [Select]
private["_a","_b","_c"];

_a = 1;

if ( _a < 3 ) then
{
   
   _b = _a + 4; // works, because _a was defined at outer scope and it is also "visible" in this block
   hint format["%1",_b];   // works, _b is accessible in the block where it was defined in

};

_c = _a + _b;    // this is WRONG, _b can't be accessed at this level!
// fix this error by initializing _b at the same scope where we initialized _a

true

The event handler is a bit like this example here, you can't access a local variable defined inside an event handler's code block outside that block. But when you make it a global variable, then it'll be accessible in all outer scopes too. It doesn't help if you initialized a local variable in your script, because the event handler doesn't use the local variables from your script at all - it has it's own local scope, totally separate from your script.

When you write scripts and functions it is good programming practice to only initialize a variable at the level where it will actually be used. That makes a lot of sense if we are using a variable only inside a block but not outside it.
« Last Edit: 23 Oct 2005, 20:01:11 by Baddo »

Lean Bear

  • Guest
Re:Local Variables with EH
« Reply #6 on: 23 Oct 2005, 20:02:52 »
If you mean that, in your example, _a is acting like a global variable, then OK, it makes sense.

But, it might have just confused me. If _a is a local variable that is initialized first, outside the scope, then it can be used in the scope. Then surely using that in a script should work? But it doesn't anyway - so I guess you meant the first thing :P

Any ideas on how I could simulate using a local variable in an EH? - a global just will not work with the script I'm using. There's more than one unit using the script, so if the variable unitDead is set to true, everyone will die - if you get me.

I need it specific to the script. (It could just be a counter, and I can set the local variable to 0 or 1 depending on whether it is true or not...

Offline Baddo

  • Former Staff
  • ****
  • Reservist Jaeger
Re:Local Variables with EH
« Reply #7 on: 23 Oct 2005, 20:13:39 »
:) heh yeah I thought I might confuse you with that example. But the event handler just doesn't take the local variables from your script at all - it has to be considered as a separate unit. Maybe the example I wrote wasn't particularly good for this event handler problem you have. It just shows what a scope means in a script / function, but it doesn't mean that the "_a" variable would be visible inside an event handler's scope.

One solution for your problem would be to make all the units have there own global variable, like unit01dead, unit02dead etc...

But that might be annoying to do if you have lots of units.

#EDIT:

Maybe you could utilize the _this select 0 from the event handler, to identify which specific unit died.
« Last Edit: 23 Oct 2005, 20:15:12 by Baddo »

Offline Baddo

  • Former Staff
  • ****
  • Reservist Jaeger
Re:Local Variables with EH
« Reply #8 on: 23 Oct 2005, 20:37:35 »
If all you need to do is to run a series of commands when a certain unit dies, then you could just attach the event handler to the unit in the unit's initialization field:

Code: [Select]
this addEventHandler ["killed", { _this select 0 exec "script.sqs" }]
And then do in your script whatever you want:

Code: [Select]
hint format ["%1 just went and died!", _this]
Because I haven't seen your script as a whole, I don't know if this would work in your situation. But this way all units will get their own scripts only when they die - and the information who died will be passed to the script.


If your situation allowes, you could also run all necessary commands straight from the event handler - no scripts needed at all:

Code: [Select]
this addEventHandler ["killed", {hint format ["%1 just went and died!",_this select 0]; 5 setFog 0.9; playMusic ["Track13", 30]  }]
This method where the needed commands are being used straight from the event handler will cause less stress on the computer for sure, because no script files need to be read. So this would be the best solution, just if you can use it in your situation.
« Last Edit: 23 Oct 2005, 20:40:25 by Baddo »

Lean Bear

  • Guest
Re:Local Variables with EH
« Reply #9 on: 24 Oct 2005, 16:56:21 »
I was just using that as an example tbh. For now, the script would only be used for a few units, so the specific global variables seems to be my best bet.

I am actually using the "fired" variable to check who fired, then, if its the right guy, to continue with the script. Sorta, its a bit more then that - but that's all I need the EH for. That would seem easy enough:

Code: [Select]
_unit = _this select 0
_unit do whatever

But then I need to also know if a variable is true or not after the fired EH is activated - which is how I got in this mess in the first place.


Quote
no scripts needed at all:

I think there's a few too many commands and too complex to just bung them in the scope ( ;) ) of the EH. Also, there's labels and stuff - but if I could just put it all onto one line and stick it in the EH, that would be the best solution of all :)

Well, you sure gave me a lot of options to try out :) So I'll be busy experimenting to see which gives the best result. Thanks! :D