0 registered members (),
16,302
guests, and 5
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
Variable scope within events
#183776
02/13/08 23:48
02/13/08 23:48
|
Joined: Feb 2008
Posts: 39
RicheyMB2
OP
Newbie
|
OP
Newbie
Joined: Feb 2008
Posts: 39
|
If you have a global variable (varGlobal) that you send to clients with send_var can you be sure that varGlobal will contain the same value if you call another function. I know you cannot be sure after a wait command but not sure about when you leave a function. Hopefully the comments in my code explain what I mean. Code:
var varGlobal ... function DoSomethingWithGlobalVariable() { //Are we sure varGlobal is the same here as when event was raised?
wait(1); //varGlobal may not contain the same value now as wait continues other functions } ... function on_client_event(void* data, var id) { if (event_type==EVENT_VAR) { if (data==&varGlobal) { //varGlobal now contains the value sent by the server. DoSomethingWithGlobalVariable() } } }
|
|
|
Re: Variable scope within events
[Re: fastlane69]
#183778
02/16/08 10:50
02/16/08 10:50
|
Joined: Jun 2001
Posts: 1,004 Dossenbach
nfs42
Serious User
|
Serious User
Joined: Jun 2001
Posts: 1,004
Dossenbach
|
Quote:
If you receive another event_var during your dosomething() function, the global var will change to this new number.
this should never happen in an event function as long as you don't use wait(). otherwise this event concept didn't worked reliable before local vars were introduced ?!
what happens, if a new event occurs before you copied the global var to the local ??
Andreas GSTools - Home of GSTScript 0.9.8: lua scripting for A6/7/8 GSTNet 0.7.9.20: network plugin for A6/7/8 GSTsqlite 1.3.7: sql database plugin for A6/7/8 3DGS Codebase: 57 snippets || 3DGS Downloads: 248 files
|
|
|
Re: Variable scope within events
[Re: Excessus]
#183780
02/16/08 18:36
02/16/08 18:36
|
Joined: Mar 2003
Posts: 5,377 USofA
fastlane69
Senior Expert
|
Senior Expert
Joined: Mar 2003
Posts: 5,377
USofA
|
Quote:
The global var will keep its value untill an instruction is executed where other events can be processed.
Hmmm... I'm pretty sure that since this is a global variable and it's being used on the network, that this is not the case.
Consider that dosomething takes 10 seconds to execute (just for the sake of arguement). During second 5, the application received another var. Were is that var stored? How does tha application KNOW not to overwrite it because another function is using it? Is the new event placed on hold while the old event finishes? I think the answers are the var is stored in the same variable, the application doesn't know that this var is being used in a event function (it's global after all), and the application can't wait for the old event to finish or it wouldn't be an "event". I could be wrong on some or all of these ponts, but since this is a global variable, there is only one, and the application has no idea to "stack" the incoming variables because it's being used, I don't see how it could be otherwise. It would be radically different if the variable were local to the event. In this case, each event would create a new variable onto which to store the value coming in and then it would work as you want, with each new event not interfering with anothers value. This is the way I see events and variables...
Quote:
what happens, if a new event occurs before you copied the global var to the local ??
As to what happens as if you get an event while you are copying, that is, in my mind an impossibility. Once the event is triggered, if the first thing you do is copy it to another variable, the new event would have to "sneak in" during the .0001 ms that it takes to copy from one variable to another. I don't know that events are based on framerate or independent of it, but the time it takes to copy a variable from on to another is so short, it's hard to believe that you will ever run into a situation where you have a new, incoming copy ursurping the ongoing, old copy.
(PS: If anyone is willng, a simple test program would solve this issue: create a server that prints out the value of a var from dosomething() every time it's triggered. Have dosomething() do something that takes some time (but no wait)... some long calculation using the var perhaps. Have the client rapid fire changing vars in a predictable pattern. Then compare the diag() output with what you sent. If it's as I say, you should see divergence of results as new vars are overwritten mid-calculation in dosomething(). If it's as you say, the calculations will remain the same on client and server regardless of the speed that you send the vars down)
|
|
|
Re: Variable scope within events
[Re: fastlane69]
#183781
02/17/08 09:33
02/17/08 09:33
|
Joined: Jan 2004
Posts: 2,013 The Netherlands
Excessus
Expert
|
Expert
Joined: Jan 2004
Posts: 2,013
The Netherlands
|
The engine can only choose to fire events (or do whatever else it has to do), when it is in controll. It is only in controll when your processor is executing instructions from the engine code, and not from your script. Your script is (implicitly) made to return to the engine code at several points (end of function, wait, engine functions).
So it is only at these times in your script, that the engine could possibly (!) choose to start another function (and an event is just a function). The engine doesn't check for events every time it is in controll (would be ridiculous if it fired events during a vec_set, for example), but it does in certain engine functions that can trigger events themselves, during wait and when a function is finished.
The way it checks for events is by looking at a queue of events to be processed. The networking thread (which DOES run in parallel to the script/engine) puts a new event on this queue when it receives a "update var" packet. The networking thread can't fire the event by itself, because then multiple functions would run in parallel, burdening the scripter with all the difficulties of concurent programming. If you know anything about concurent programming, you'll know this is not the case.
The way I see it, there is no way to program the engine to behave like you explained. On a low level, "events" don't exist. So they must somehow be fit into the inherently serial way a computer operates. When the scheduler starts a function, the scheduler is not running itself. So it can't possibly pause/abort/start another function, or set the value of a global var.
|
|
|
Re: Variable scope within events
[Re: Excessus]
#183782
02/17/08 19:33
02/17/08 19:33
|
Joined: Mar 2003
Posts: 5,377 USofA
fastlane69
Senior Expert
|
Senior Expert
Joined: Mar 2003
Posts: 5,377
USofA
|
I understand that Events are a fake multi-thread and that 3DGS only has 1 thread and is serial. But my point isn't with the events, it's with the global variable that is also a network variable. A var, ultimitely, is a memory address. One global var means one memory address. Hence, if you are sending data on that var, it is irrelevent (IMO) which event you are on... the second that I receive a var, that memory address changes regardless of which function you are on. So pursuiant to my example above (which I would love to whip out by the GDC is this week), if I send a var =10 and have my event print out 1000 times "this is the var = %f", the output will be "this is the var = 10" a thousand times. Now, assume that halfway though the event operation, I send a var = 5. Then, AFAIK, there will be "this is the var = 10" 500 times followed "this is the var = 5" for the following 500 times since the memory address changed mid-way through the event operation. So the event function is unchanged and will proceed serially as you descrbe. But the VALUES that the global variables take are not tied into the event and thus can change independent of the event you are currently on. This is why it has always been my impression (and I'm sure I read it in the My understanding comes from this line in the manual Quote:
If you want to keep them longer, copy them to local variables or entity skills. For clarity, let the entities' main action do most of the work, and keep the event function as short and simple as possible, without any wait instructions.
Specifically the "keep the event short and simple" and "copy them to a local variable or skill".
|
|
|
Re: Variable scope within events
[Re: fastlane69]
#183783
02/17/08 20:04
02/17/08 20:04
|
Joined: Jan 2004
Posts: 2,013 The Netherlands
Excessus
Expert
|
Expert
Joined: Jan 2004
Posts: 2,013
The Netherlands
|
Quote:
the second that I receive a var, that memory address changes regardless of which function you are on.
That's not true. The networking thread will receive a packet which contains the index of the variable, and its new contents. It doesn't have to update the var right away.
Actually, updating the variable right away would be a very bad idea. It makes much more sense to update the var right before the event function is executed (if there is no event function assigned, nothing is called but that's irrelevant). Updating the var as soon as you receive it would violate some basic rules of concurent programming. Some things that could happen: -You don't know how much time the OS will assign to each thread, so it could very well be that two updates to the same var are processed by the networking thread (so the var is updated twice, if you are correct), before the script/engine thread is able to process the events -> lost update. (Think about that, it would be a horrible, random occuring bug, depending on how you use vars/events in your script) -In the case of larger datastructures, it could be that the struct has only partially been updated when the OS switches to the script thread. The scripting thread could then read the inconsistent structure. This causes you to read structs in your events that where never sent, bad..
I think you have interpreted the manual wrongly (or you just want to be right very badly yea I know you ).
Quote:
After start of an event function, all event-dependent variables and pointers, like normal etc., keep their values only until the next wait instruction. During the wait pause they can (and certainly will) be changed by other functions. If you want to keep them longer, copy them to local variables or entity skills. For clarity, let the entities' main action do most of the work, and keep the event function as short and simple as possible, without any wait instructions.
I read that as "if you want to retain the original value after the first wait, store it in a local var".
If you are right, you have found the cause of your random crashes.
|
|
|
Re: Variable scope within events
[Re: Excessus]
#183784
02/17/08 23:21
02/17/08 23:21
|
Joined: Jun 2001
Posts: 1,004 Dossenbach
nfs42
Serious User
|
Serious User
Joined: Jun 2001
Posts: 1,004
Dossenbach
|
Quote:
so it could very well be that two updates to the same var are processed by the networking thread (so the var is updated twice, if you are correct), before the script/engine thread is able to process the events -> lost update.
according to Murphy's law this will happen
it's still hypothetic, you have to know how directplay is embedded.
i.e. GSTNet is queued, the queue is processed per polling. with one poll you get 0 packet from 0 client or 10 packets from 6 clients. events were raised only during the poll. so there should be NO wait instruction in the event function, which would cause a new queue poll.
try to handle an event like interrupt on a cpu - push registers on stack - keep interrupt routine lean and short - pop your stack before you quit the interrupt routine ;-)
Andreas GSTools - Home of GSTScript 0.9.8: lua scripting for A6/7/8 GSTNet 0.7.9.20: network plugin for A6/7/8 GSTsqlite 1.3.7: sql database plugin for A6/7/8 3DGS Codebase: 57 snippets || 3DGS Downloads: 248 files
|
|
|
Re: Variable scope within events
[Re: nfs42]
#183785
02/18/08 07:09
02/18/08 07:09
|
Joined: Mar 2003
Posts: 5,377 USofA
fastlane69
Senior Expert
|
Senior Expert
Joined: Mar 2003
Posts: 5,377
USofA
|
Wanting to be right doesn't make it so. That kind of thinking is fine for Morbius but not here... and I know I'm not in Morbius.  What you say makes perfect sense and I hope I'm wrong and you are right. But this assumes that Conitec did it that way and as we both know, networking is NOT their strong suit and so I always lean towards the "incorrect" way of doing things and not the "correct" way.  I think I'll post this question in Ask Conitec. On the other hand, if you have the time, a simple test program could also verify if the network packet is copied at the time of receipt as I suggest or at the time of event execution as you suggest. Actually, the test is the only way to prove this since Conitec has proven all to often that they really don't know what is going on with their network engine sometimes (or it may be at the DirectX level and thus TRULY mysterious!). 
|
|
|
|