🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

upgrading to 2.5 : reference issues.

Started by
6 comments, last by WitchLord 18 years, 4 months ago
I've just upgraded to AS 2.5. Needless to say, everything worked fine with 2.41d ;) I have a function registered as : "bool LoadTexture(const string ∈, bool, bool, Texture &inout)" in the script, I call : " Texture texture; void Init() { LoadTexture("Textures\\Backgrounds\\*", true, false, texture); } " which results in : "Line (24, 56) : Cannot guarantee safety of reference. Copy the value to a local variable first" (this points to the use of 'texture' as the last parameter) Can you explain what's changed / whats going on ? Edit: Okay, if I change the code according to the error to " Texture texture; void Init() { Texture local_tex; LoadTexture("Textures\\Backgrounds\\*", true, false, local_tex); texture = local_tex; } " it works as expected. But this is hardly what I'd expect scripters to write. Any solution for this ? Otherwise I'd sadly be forced to keep using 2.41d :( [Edited by - LDenninger on January 17, 2006 6:07:21 PM]
_-=[ "If there's anything more important than my ego around, I want it caught and shot now." ]=--=[ BeatHarness ]=-=[ Guerrilla Games ]=-=[ KillZone ]=-
Advertisement
I'm sorry for the inconvenience. I'm trying to find the right formulae for the parameter references, and even though the current way (2.5.0) isn't perfect either, I believe it is better than the way it was in (2.4.1).

In 2.4.1 the script had to evaluate the argument expression both before and after the function call, which could lead to confusing bugs. The compiler warned if the expression was complex though, but it still wasn't very good. The reference that was passed to the function wasn't the true reference either, but a copy of the value.

Now the script evaluates the expression only once, and passes the true reference. The script engine still has to guarantee that the reference will be valid during the entire function call however, which is why I have restricted the possible expressions to local variables, or objects that support object handles.

This may still cause confusion, such as in your case. So I may actually remove the support for local variables entirely and only permit the &inout for object types that support handles. At least that way it will be more consistent.

Now for the solution to your problem. There are three ways that you can work around the problem.

1. Add handle support for the Texture type (register the addref and release behaviours). With this no further changes to your scripts are necessary.

2. Compile the library with the flag asALLOW_UNSAFE_REFERENCES. With this the script engine will handle parameter reference just like normal C++ references, i.e. any expression goes and the true reference will be passed to the function. ∈, and &out, references still work the same in both modes, though. With unsafe references it will be up to the programmer to guarantee the validity of the references though. It will be possible to write scripts that crashes the application as it accesses invalid references.

3. Rewrite your function to take a Texture &out, instead of Texture &inout. It seems to me that a function LoadTexture() wouldn't need to take any input texture. Though if you need an input texture you could perhaps add another parameter with a Texture &in.

I hope you can accept one of these solutions. I'm sure that in time I will find the perfect solution for the parameter references, in meantime I hope you all will be patient as I change the way they work from time to time.

Regards,
Andreas

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

As you said, I've changed the last parameter of LoadTexture to & out.
("bool LoadTexture(const string ∈, bool, bool, Texture &out)")

Indeed the last parameter didn't need the "inout", it's just an output. :)
So then BH ran nicely, handled the rest of the scripts perfectly... UNTIL :D

A script that said :

"float nBass=1.0f;

void Foo(float v, float &inout nv)
{
nv = (1.0f - gTimeDelta) * nv + gTimeDelta * v;
}

void Draw()
{
Foo(gBass, nBass);
// blah here
}
"

(gTimeDelta and gBass are floats and registered globally from code)


Anyway, the same error/warning as before - an unsafe reference.
(only this time in a script function)
Your previous suggestions worked - so uhm...
got any help on this one ..? ;)
_-=[ "If there's anything more important than my ego around, I want it caught and shot now." ]=--=[ BeatHarness ]=-=[ Guerrilla Games ]=-=[ KillZone ]=-
To make a long story very short, my current problem seems to be :

"
float temp;
float temp2;


float Foo(a,b)
{
return a*b*blah;
}

void TheMainFunction()
{
float thingie = Foo(temp, temp2);
}
"


Any suggestions (aside from asALLOW_UNSAFE_REFERENCES :)) ?
_-=[ "If there's anything more important than my ego around, I want it caught and shot now." ]=--=[ BeatHarness ]=-=[ Guerrilla Games ]=-=[ KillZone ]=-
Don't knock asALLOW_UNSAFE_REFERENCES. The situation that can crash is exactly the same as in C++. Since scripts can't do memory allocation/deallocation directly, any invalid reference created by a script is ultimatly a bug in your bound interface. If you're careful, users still can't write a script that crashes the app. And if scripting isn't part of the gameplay - and I bet it isn't - then any scripting the users do will be to make mods or cheat anyway, and then it's not your problem if it crashes.
The only problem is the &inout version of parameter references. Both ∈, and &out work for all types of expressions.

The only suggestion I can make is to write your code so that &inout isn't used for anything but types that support object handles. Think about how you would solve the problem in Java, that don't even have parameter refences for non-object type.

Regards,
Andreas

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Quote: Original post by WitchLord
The only problem is the &inout version of parameter references. Both ∈, and &out work for all types of expressions.

The only suggestion I can make is to write your code so that &inout isn't used for anything but types that support object handles. Think about how you would solve the problem in Java, that don't even have parameter refences for non-object type.

Regards,
Andreas


I guess I'll have to start learning Java 'cause I'm completely lost in the woods on this comment ;)
_-=[ "If there's anything more important than my ego around, I want it caught and shot now." ]=--=[ BeatHarness ]=-=[ Guerrilla Games ]=-=[ KillZone ]=-
In Java, there is no option to pass arguments by value or by reference. Instead the language is written so that all primitives are always passed by value, and all classes are passed by reference. This makes it necessary to think slightly different from how you would in C++.

I'm not a big fan of Java myself, but I can understand why they made that choice when designing the language. Doing that, they kept the language simple, and still made sure that it is safe from references becoming invalid before they are used. I think it is too restrictive though.

With AngelScript I'm trying to keep as much of C++'s flexibility as possible, while still making the language safe. This means that I'll have to make a compromise between the way Java went and the way C++ does it.


AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement