Factory from class

Started by
4 comments, last by onattoglu 12 years, 9 months ago
Hi there,
I'm using Angelscript for my game, it's going good so far except I had a problem I couldn't solve although I've tried everything. I've been reading the documentation but there was no reference there for this, so I'm posting it here.

r = engine->RegisterObjectBehaviour("Input", asBEHAVE_FACTORY, "Input@ f()", asFUNCTION(this->ScriptInput_Factory() ), asCALL_CDECL);

See, the factory function is in this bigger class "Scripting"(so this-> is the "Scripting" class), where all scripting related things go on, like registering globals etc. When I write the function static, it works(with other objects I've tried) but this time I need a variable in Scripting to create the class. When I open the application and create the object in script the application crashes at code execution. I've also done debugging, the factory function(Scripting::ScriptInput_Factory) is called properly. So, what could it be?

ScriptInput* Scripting::ScriptInput_Factory() is the decleration of the factory function.

Thank you in advance.

Edit : Fool me.. After another debugging I noticed the code above executes the function. I've done it like this in the first place but changed it, as I thought this wasn't supposed to be the way, when I got this nasty compiler error :

r = engine->RegisterObjectBehaviour("Input", asBEHAVE_FACTORY, "Input@ f()", asFUNCTION(&Scripting::ScriptInput_Factory ), asCALL_THISCALL);


error C2440: 'type cast' : cannot convert from 'ScriptInput *(__thiscall Scripting::* )(void)' to 'size_t'
1> There is no context in which this conversion is possible
1> d:\gamedev\the new game\scripting.cpp(134) : see reference to function template instantiation 'asSFuncPtr asFunctionPtr<scriptInput*(__thiscall Scripting::* )(void)>(T)' being compiled
1> with
1> [
1> T=ScriptInput *(__thiscall Scripting::* )(void)
1> ]
Advertisement
Angelscript's function macros are pretty nice little macros. You just need to specify the function name without having to worry about the usual C++ syntax.

r = engine->RegisterObjectBehaviour("Input", asBEHAVE_FACTORY,"Input@ f()",asMETHOD(Scripting,ScriptInput_Factory),asCALL_THISCALL);

Although you should really be registering these factory functions as global functions.
Yes I've tried that one as well before, it doesn't work. The error code from the exact same code is : -7 - asNOT_SUPPORTED.
Edit : The reason I cannot register the factory functions is as I stated above, I need to access a certain variable from Scripting. So, another solution would be :
ScriptInput* ScriptInput_Factory(Scripting*);

But the problem is, how can I pass the pointer to the function from the macro?
Factories can only be registered as global functions, or static methods, which really are the same thing except for the namespace.

Assuming a static method, the following is the correct syntax:



r = engine->RegisterObjectBehaviour("Input", asBEHAVE_FACTORY, "Input@ f()", asFUNCTION(Scripting::ScriptInput_Factory), asCALL_CDECL); assert( r >= 0 );




Observe, no &, and asCALL_CDECL.


The factory can receive parameters, just like a constructor, but this means the script needs to pass them. However, I assume you want to be able to store some data that the factory can access without the script having to inform it.

If you don't want to use global variables (or static members of the class) to hold that information, you can use the engine's user data, or even the context's user data to store it for you. If you use the engine's user data, you can retrieve it as the following:



// Static method
Input *Scripting::ScriptInput_Factory()
{
asIScriptContext *ctx = asGetActiveContext();
asIScriptEngine *engine = ctx->GetEngine();
void *userData = engine->GetUserData();

// Do something with the user data
}



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

It worked, thanks a lot!
Hey there again,
I've ran into another problem. See, my class "Player", which is all declared in the script, is instanciated by C++ and then a pointer to the instanciated asIScriptObject is stored. Now I want to return this stored object back to script to use it from the script :) I know, sounds a bit strange, but as I designed my game, I did not foresee that I was demanding more of Angelscript, in favor of security purposes, as I'm making a multiplayer game.
Well anyway, is there a way to do it without Any-addon? How should I do it with any-addon, I've tried but failed.
Thanks in advance!

Solved the problem by finding a way around. I have completely forgotten that Player was derived from an interface. As the interfaces are predefined(registered in c++ by me), I can pass them to the script and then cast them.

http://www.angelcode.com/angelscript/sdk/docs/manual/doc_script_handle.html

Hope it helps somebody.
Cheers, Onat.

This topic is closed to new replies.

Advertisement