So this probably has been done, but I'm wondering if there was a better way to do this. I wrote a global templated function that allows you to use it as the pointing function for any class's constructor reference. Looking at the stringD code I saw there are 2 ways to go about doing this: Usinging asIScriptGeneric, and Calling it natively using a typed member object pointer.
Below is some code that does both based on the as_max_portiblity preprocessor define that I created (i assume there is one natively in the engine but I didn't see it):
asERRORCHECK(r) assert(r < 0) //I have a much more complex error message system, so this is just to cover for that
#define as_max_portiblity 0
#if as_max_portiblity
template<class C, typename ...Args> void __constructor__(asIScriptGeneric *gen)
{
int i = 0, max = sizeof ...(Args);
new (gen->GetObject()) C(*static_cast<Args *>(gen->GetAddressOfArg(*std::make_unique<int>((max-(++i)))))...);
}
#else
template<class C, typename ...Args> void __constructor__(C *gen, Args... args)
{
new (gen) C(Args(args)...);
}
#endif
Once you have defined the type of function you want to use then you need to register this inside of a function like this:
void registermyobjects(asIScriptEngine *asEngine)
{
int r;
...
//we have an object registered under the name vec2
...
#if as_max_portiblity
r = asEngine->RegisterObjectBehaviour("vec2", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(__constructor__<vec2>), asCALL_GENERIC); asERRORCHECK(r);
r = asEngine->RegisterObjectBehaviour("vec2", asBEHAVE_CONSTRUCT, "void f(float, float)", asFUNCTION((__constructor__<vec2, float, float>)), asCALL_GENERIC); asERRORCHECK(r);
#else
r = asEngine->RegisterObjectBehaviour("vec2", asBEHAVE_CONSTRUCT, "void f()", asFUNCTIONPR((__constructor__<vec2>), (vec2 *), void), asCALL_CDECL_OBJFIRST); asERRORCHECK(r);
r = asEngine->RegisterObjectBehaviour("vec2", asBEHAVE_CONSTRUCT, "void f(float, float)", asFUNCTIONPR((__constructor__<vec2, float,float>),(vec2 *,float, float), void), asCALL_CDECL_OBJFIRST); asERRORCHECK(r);
#endif
...
}
This should be fairly self explanatory but i have a class vec2 which can take either (void) or (float,float) as its constructor types. So this should in theory be able to take anytype and pass it into the __constructor__() and it will create an object for you. Let me know what you think.
Im curious if anyone has done something like this, or if any one sees a potential problem with this code. In theory I could do the same thing for operator types and maybe even factory functions.
chasester
@edit 1: Made a mistake where the new int(++i) was passing maxargs ... 0 rather than 0 .... maxargs. Fixed by reversing the numbers with a formula (((++i) - maxargs)*-1).
@edit 2: Made max - (++i) so that we dont have to multiply by -1. Also replace *new int() with *std::make_unique<int>() so that we dont run into a memory leak.