Sign in to follow this  
saejox

Get name of a primitive passed as parameter to C++

Recommended Posts

Hi,

like this, in script
[CODE]
Load(int_variable);
[/CODE]
in c++
[CODE]
void Load(void *ref, int typeId)
{
// find name of ref, not type name
}
[/CODE]

script copies and passes a temp value to c++
i cant use @int_variable to pass the actual pointer.

i currently pass a name as a string then iterate over properties and find value.
but that is slow. ( Load(const string &in) )

is there a way to get address of primitives?

thanks.

Share this post


Link to post
Share on other sites
I'm afraid I don't understand what you're trying to accomplish.


What is the Load() function supposed to do? Return an integer value?

If it is then you should register it as &out, i.e. an output reference.

[code]
// script
void func()
{
int variable;
Load(variable);
assert( variable == 42 );
}

// C++
// Registered with signature "void Load( ? &out )"
void Load(void *ref, int typeId)
{
if( typeId == asTYPEID_INT32 )
{
*(int*)ref = 42;
}
}

// or with signature "void Load(int &out)"
void Load(int &var)
{
var = 42;
}
[/code]

Share this post


Link to post
Share on other sites
Is this intended to be some lightweight way for (limited) saving of the script's state? For that, you can check out the Serializer addon: http://www.angelcode.com/angelscript/sdk/docs/manual/doc_addon_serializer.html

Share this post


Link to post
Share on other sites
[quote name='TheAtom' timestamp='1341431436' post='4955714']
Is this intended to be some lightweight way for (limited) saving of the script's state? For that, you can check out the Serializer addon: [url="http://www.angelcode.com/angelscript/sdk/docs/manual/doc_addon_serializer.html"]http://www.angelcode...serializer.html[/url]
[/quote]

you are really insightful. :)
you did same with my other thread by asking unary operator.
i wish i understood what code does just by looking 4 lines of it :)

about serializer addon, it is not what i want.
i want same syntax as boost::serialization library.

[u]here is a better explanation of what i want to do:[/u]

i just want to learn name of that integer, i dont want change or return it.

i already register it as Load(?&out)

pointer i get is not same as it is in script. so i cant find its name

here is how it works
[CODE]
class Test
{
int a;
float b;
Test2 child; // this has its own Serialize() function


Serialization @Serialize()
{
Serialization @ser;
@ser = CreateSerialization(@this);

ser << a; // << operator is Load(?&out)
ser << b;
ser << @child;

return @ser;
}

}
[/CODE]

Share this post


Link to post
Share on other sites
Perhaps this can be of use: [url="http://pastebin.com/bQ0j8YMV"]http://pastebin.com/bQ0j8YMV[/url]
It has some stuff specific to the game it is from, and requires some extra engine functions to be able to serialize floats. It does not know the name of the resource it tries to serialize though, so it relies on the order of << and >> calls.

Share this post


Link to post
Share on other sites
[quote name='TheAtom' timestamp='1341491361' post='4955949']
Perhaps this can be of use: [url="http://pastebin.com/bQ0j8YMV"]http://pastebin.com/bQ0j8YMV[/url]
It has some stuff specific to the game it is from, and requires some extra engine functions to be able to serialize floats. It does not know the name of the resource it tries to serialize though, so it relies on the order of << and >> calls.
[/quote]

thanks, i will use some parts of this in binary output portion.
i had some goals starting this,
- human readable output
- order of saved variable do not matter
- adding new variable does not corrupt old saves
- removing variables does not corrupt saved files
- no need to modify c++ code

to be used in:
- save/load object to file
- debugger, readable text dump of objects
- transfer state over tcp

but i just cant find a way to learn primitives' name when they are passed as references.
i am stuck with
ser << "int_var";
but i want
ser << int_var;

Share this post


Link to post
Share on other sites
I'm afraid it simply doesn't work that way. In order to guarantee that the reference sent to a function AngelScript will sometime have to send a reference to a temporary variable rather than to the real one, when there may be a change the real one is destroyed during the function call.

You can turn on unsafe references, which will let AngelScript send the reference to the real variable as an &inout reference. However, I cannot guarantee that this will allow you to find the name of the real variable in all instances.

To turn on unsafe referecences, the application should call:

[code]
engine->SetEngineProperty(asEP_ALLOW_UNSAFE_REFERENCSE, true);
[/code]

Remember, a badly written script can crash the application if you turn this on.

Share this post


Link to post
Share on other sites
[quote name='Andreas Jonsson' timestamp='1341497462' post='4955982']
I'm afraid it simply doesn't work that way. In order to guarantee that the reference sent to a function AngelScript will sometime have to send a reference to a temporary variable rather than to the real one, when there may be a change the real one is destroyed during the function call.

You can turn on unsafe references, which will let AngelScript send the reference to the real variable as an &inout reference. However, I cannot guarantee that this will allow you to find the name of the real variable in all instances.

To turn on unsafe referecences, the application should call:

[code]
engine->SetEngineProperty(asEP_ALLOW_UNSAFE_REFERENCSE, true);
[/code]

Remember, a badly written script can crash the application if you turn this on.
[/quote]

came this far without using asEP_ALLOW_UNSAFE_REFERENCE, i am scared of it :)
passing as string is ok
thanks.

Share this post


Link to post
Share on other sites
You said the issue with the original technique was the need to iterate through all your member variables -- is making a hashmap acceptable? It still involves processing a string, but operates in ~O(1) time.

Share this post


Link to post
Share on other sites
[quote name='saejox' timestamp='1341506086' post='4956019']
came this far without using asEP_ALLOW_UNSAFE_REFERENCE, i am scared of it
[/quote]

Don't be. My team has been using it since close to 3 years already and the only time we had a crash related to it turned out to be an obscure bug somewhere in AS which was fixed very quickly afterwards by Andreas. The setting does make life easier.

Share this post


Link to post
Share on other sites
Indeed, the references are no more 'unsafe' than references are in C++. Badly written C++ code can also crash the application, but with proper testing you avoid that.

It's mostly a question of how far you're willing to go to keep the scripts in a sandbox, i.e. do you trust the script writers to properly test the scripts and not willfully attempt to sabotage the application?

Just to put things in perspective, here's an example where an unsafe reference could possibly cause a crash:

[code]
array<int> arr = {1,2,3};
int DoSomething(int& refToInt)
{
// Resize the global array, which will deallocate the
// old internal buffer that our reference points to
arr.resize(100);

// Do some more stuff

// Change the value of the refToInt
refToInt = 42; /// <--- Oops, the reference is no longer pointing to the array element
}
void main()
{
// Call the function with a reference to one of the elements in the array
DoSomething(arr[0]);
}
[/code]

Depending on exactly what was allocated on the heap where the array was originally allocated, the update that is made to the reference may be harmless, corrupt the heap, or overwrite some other pointer, etc.

Without unsafe references, the compiler guarantees that an error like this cannot be made (willfully or not).

Regards,
Andreas

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this