Re: Invalid static_cast registering class to Angelscript
Posted: Thu Aug 11, 2011 12:16 pm
by zerochen
[admin edit] the code seems to make problems with the code highlighting. I've disabled bbcodes to at least see the code. Maybe move it over to some source hoster.[/admin edit]
yeah thx...
if you need the vector3d in angelschript here we go:
CScriptVector3d.h
[code]
#ifndef CSCRIPTVECTOR3D_H
#define CSCRIPTVECTOR3D_H
#include <angelscript.h>
#include <assert.h>
#include <string>
#include <sstream>
#include <new>
#include <typeinfo>
#include "vector3d.h"
BEGIN_AS_NAMESPACE
using namespace irr;
class Vector3d
{
public:
template<typename T>
static void Vector3dDefaultConstructor(core::vector3d<T>* self)
{
new(self) core::vector3d<T>();
}
template<typename T>
static void Vector3dCopyConstructor(const core::vector3d<T> &other, core::vector3d<T>* self)
{
new(self) core::vector3d<T>(other);
}
template<typename T>
static void Vector3dInitConstructor(T x, T y, T z, core::vector3d<T>* self)
{
new(self) core::vector3d<T>(x,y,z);
}
template<typename T>
static void Vector3dInit2Constructor(T n, core::vector3d<T>* self)
{
new(self) core::vector3d<T>(n);
}
//-----------------------
// Generic calling convention
//-----------------------
template<typename T>
static void Vector3dDefaultConstructor_Generic(asIScriptGeneric *gen)
{
core::vector3d<T> *self = (core::vector3d<T>*)gen->GetObject();
new(self) core::vector3d<T>();
}
template<typename T>
static void Vector3dCopyConstructor_Generic(asIScriptGeneric *gen)
{
core::vector3d<T> *other = (core::vector3d<T>*)gen->GetArgObject(0);
core::vector3d<T> *self = (core::vector3d<T>*)gen->GetObject();
Vector3dCopyConstructor(*other, self);
}
template<typename T>
static void Vector3dInitConstructor_Generic(asIScriptGeneric *gen)
{
T* x = (T*)gen->GetArgAddress(0);
T* y = (T*)gen->GetArgAddress(1);
T* z = (T*)gen->GetArgAddress(2);
core::vector3d<T> *self = (core::vector3d<T>*)gen->GetObject();
Vector3dInitConstructor(*x, *y, *z, self);
}
template<typename T>
static void Vector3dInit2Constructor_Generic(asIScriptGeneric *gen)
{
T* n = (T*)gen->GetArgAddress(0);
core::vector3d<T> *self = (core::vector3d<T>*)gen->GetObject();
Vector3dInit2Constructor(*n, self);
}
/* functions */
template<typename T>
static void getLength(asIScriptGeneric *gen)
{
core::vector3d<T> *s = (core::vector3d<T>*)gen->GetObject();
*(T*)gen->GetAddressOfReturnLocation() = s->getLength();
}
template<typename T>
static void getLengthSQ(asIScriptGeneric *gen)
{
core::vector3d<T> *s = (core::vector3d<T>*)gen->GetObject();
*(T*)gen->GetAddressOfReturnLocation() = s->getLengthSQ();
}
template<typename T>
static void dotProduct(asIScriptGeneric *gen)
{
core::vector3d<T> *s = (core::vector3d<T>*)gen->GetObject();
*(T*)gen->GetAddressOfReturnLocation() = s->dotProduct(*(core::vector3d<T>*)gen->GetArgObject(0));
}
template<typename T>
static void getDistanceFrom(asIScriptGeneric *gen)
{
core::vector3d<T> *s = (core::vector3d<T>*)gen->GetObject();
*(T*)gen->GetAddressOfReturnLocation() = s->getDistanceFrom(*(core::vector3d<T>*)gen->GetArgObject(0));
}
template<typename T>
static void getDistanceFromSQ(asIScriptGeneric *gen)
{
core::vector3d<T> *s = (core::vector3d<T>*)gen->GetObject();
*(T*)gen->GetAddressOfReturnLocation() = s->getDistanceFromSQ(*(core::vector3d<T>*)gen->GetArgObject(0));
}
template<typename T>
static void crossProduct(asIScriptGeneric *gen)
{
core::vector3d<T> *s = (core::vector3d<T>*)gen->GetObject();
gen->SetReturnObject(&s->crossProduct(*(core::vector3d<T>*)gen->GetArgObject(0)));
}
template<typename T>
static void isBetweenPoints(asIScriptGeneric *gen)
{
core::vector3d<T> *s = (core::vector3d<T>*)gen->GetObject();
*(bool*)gen->GetAddressOfReturnLocation() = s->isBetweenPoints(*(core::vector3d<T>*)gen->GetArgObject(0), *(core::vector3d<T>*)gen->GetArgObject(1));
}
template<typename T>
static void normalize(asIScriptGeneric *gen)
{
core::vector3d<T>* s = (core::vector3d<T>*)gen->GetObject();
gen->SetReturnObject(&s->normalize());
}
template<typename T>
static void toString(asIScriptGeneric *gen)
{
core::vector3d<T> *s = (core::vector3d<T>*)gen->GetObject();
std::ostringstream retVal;
retVal << "X: ";
retVal << s->X;
retVal << " Y: ";
retVal << s->Y;
retVal << " Z: ";
retVal << s->Z;
std::string ret(retVal.str());
gen->SetReturnObject(&ret);
}
/* operators */
template<typename T>
static void vector3dfEqualGeneric(asIScriptGeneric *gen)
{
core::vector3d<T> *a = (core::vector3d<T>*)gen->GetObject();
core::vector3d<T> *b = (core::vector3d<T>*)gen->GetArgAddress(0);
*(bool*)gen->GetAddressOfReturnLocation() = b->equals(*a);
}
template<typename T>
static void Vector3dAddAssign_Generic(asIScriptGeneric *gen)
{
core::vector3d<T> *a = (core::vector3d<T>*)gen->GetArgAddress(0);
core::vector3d<T> *thisPointer = (core::vector3d<T>*)gen->GetObject();
*thisPointer += *a;
gen->SetReturnAddress(thisPointer);
}
template<typename T>
static void Vector3dSubAssign_Generic(asIScriptGeneric *gen)
{
core::vector3d<T> *a = (core::vector3d<T>*)gen->GetArgAddress(0);
core::vector3d<T> *thisPointer = (core::vector3d<T>*)gen->GetObject();
*thisPointer -= *a;
gen->SetReturnAddress(thisPointer);
}
template<typename T>
static void Vector3dMulAssign_Generic(asIScriptGeneric *gen)
{
T* s = (T*)gen->GetArgAddress(0);
core::vector3d<T> *thisPointer = (core::vector3d<T>*)gen->GetObject();
*thisPointer *= *s;
gen->SetReturnAddress(thisPointer);
}
template<typename T>
static void Vector3dDivAssign_Generic(asIScriptGeneric *gen)
{
T* s = (T*)gen->GetArgAddress(0);
core::vector3d<T> *thisPointer = (core::vector3d<T>*)gen->GetObject();
*thisPointer /= *s;
gen->SetReturnAddress(thisPointer);
}
template<typename T>
static void Vector3dAdd_Generic(asIScriptGeneric *gen)
{
core::vector3d<T> *a = (core::vector3d<T>*)gen->GetObject();
core::vector3d<T> *b = (core::vector3d<T>*)gen->GetArgAddress(0);
core::vector3d<T> res = *a + *b;
gen->SetReturnObject(&res);
}
template<typename T>
static void Vector3dSub_Generic(asIScriptGeneric *gen)
{
core::vector3d<T> *a = (core::vector3d<T>*)gen->GetObject();
core::vector3d<T> *b = (core::vector3d<T>*)gen->GetArgAddress(0);
core::vector3d<T> res = *a - *b;
gen->SetReturnObject(&res);
}
template<typename T>
static void Vector3dFloatMulcore_Generic(asIScriptGeneric *gen)
{
//T s = gen->GetArgFloat(0);
T* s = (T*)gen->GetArgAddress(0);
core::vector3d<T> *v = (core::vector3d<T>*)gen->GetObject();
core::vector3d<T> res = *s * *v;
gen->SetReturnObject(&res);
}
template<typename T>
static void Vector3dMulFloat_Generic(asIScriptGeneric *gen)
{
T* s = (T*)gen->GetArgAddress(0);
core::vector3d<T> *v = (core::vector3d<T>*)gen->GetObject();
core::vector3d<T> res = *v * *s;
gen->SetReturnObject(&res);
}
template<typename T>
static void Vector3dDivFloat_Generic(asIScriptGeneric *gen)
{
T* s = (T*)gen->GetArgAddress(0);
core::vector3d<T> *v = (core::vector3d<T>*)gen->GetObject();
core::vector3d<T> res = *v / *s;
gen->SetReturnObject(&res);
}
//--------------------------------
// Registration
//-------------------------------------
template<typename T>
void static Vector3d_Native(asIScriptEngine *engine, std::string name)
{
s32 r;
std::string type = typeid(T).name();
// Register the type
r = engine->RegisterObjectType(name.c_str(), sizeof(core::vector3d<T>), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_CAK); assert( r >= 0 );
// Register the object properties
r = engine->RegisterObjectProperty(name.c_str(), (type + " X").c_str(), offsetof(core::vector3d<T>, X)); assert( r >= 0 );
r = engine->RegisterObjectProperty(name.c_str(), (type + " Y").c_str(), offsetof(core::vector3d<T>, Y)); assert( r >= 0 );
r = engine->RegisterObjectProperty(name.c_str(), (type + " Z").c_str(), offsetof(core::vector3d<T>, Z)); assert( r >= 0 );
// Register the constructors
r = engine->RegisterObjectBehaviour(name.c_str(), asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(Vector3dDefaultConstructor<T>), asCALL_CDECL_OBJLAST); assert( r >= 0 );
r = engine->RegisterObjectBehaviour(name.c_str(), asBEHAVE_CONSTRUCT, "void f(const vector3df &in)", asFUNCTION(Vector3dCopyConstructor<T>), asCALL_CDECL_OBJLAST); assert( r >= 0 );
r = engine->RegisterObjectBehaviour(name.c_str(), asBEHAVE_CONSTRUCT, ("void f(" + type +", "+ type +", "+ type + ")").c_str(), asFUNCTION(Vector3dInitConstructor<T>), asCALL_CDECL_OBJLAST); assert( r >= 0 );
r = engine->RegisterObjectBehaviour(name.c_str(), asBEHAVE_CONSTRUCT, ("void f(" + type + ")").c_str(), asFUNCTION(Vector3dInit2Constructor<T>), asCALL_CDECL_OBJLAST); assert( r >= 0 );
// Register the operator overloads
r = engine->RegisterObjectMethod(name.c_str(), "vector3df &opAddAssign(const vector3df &in)", asMETHODPR(core::vector3d<T>, operator+=, (const core::vector3d<T>&), core::vector3d<T>&), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), "vector3df &opSubAssign(const vector3df &in)", asMETHODPR(core::vector3d<T>, operator-=, (const core::vector3d<T>&), core::vector3d<T>&), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), ("vector3df &opMulAssign(" + type + ")").c_str(), asMETHODPR(core::vector3d<T>, operator*=, (T), core::vector3d<T>&), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), ("vector3df &opDivAssign(" + type + ")").c_str(), asMETHODPR(core::vector3d<T>, operator/=, (T), core::vector3d<T>&), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), "bool opEquals(const vector3df &in) const", asMETHODPR(core::vector3d<T>, operator==, (const core::vector3d<T>&) const, bool), asCALL_THISCALL); assert(r >= 0);
r = engine->RegisterObjectMethod(name.c_str(), "vector3df opAdd(const vector3df &in) const", asMETHODPR(core::vector3d<T>, operator+, (const core::vector3d<T>&) const, core::vector3d<T>), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), "vector3df opSub(const vector3df &in) const", asMETHODPR(core::vector3d<T>, operator-, (const core::vector3d<T>&) const, core::vector3d<T>), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), ("vector3df opMul(" + type + ") const").c_str(), asMETHODPR(core::vector3d<T>, operator*, (T) const, core::vector3d<T>), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), ("vector3df opDiv(" + type + ") const").c_str(), asMETHODPR(core::vector3d<T>, operator/, (T) const, core::vector3d<T>), asCALL_THISCALL); assert( r >= 0 );
// Register the object methods
r = engine->RegisterObjectMethod(name.c_str(), (type + " getLength() const").c_str(), asMETHOD(core::vector3d<T>, getLength), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), (type + " getLengthSQ() const").c_str(), asMETHOD(core::vector3d<T>, getLengthSQ), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), (type + " dotProduct(const vector3df &in) const").c_str(), asMETHOD(core::vector3d<T>, dotProduct), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), (type + " getDistanceFrom(const vector3df &in) const").c_str(), asMETHOD(core::vector3d<T>, getDistanceFrom), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), (type + " getDistanceFromSQ(const vector3df &in) const").c_str(), asMETHOD(core::vector3d<T>, getDistanceFromSQ), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), "vector3df crossProduct(const vector3df &in) const", asMETHOD(core::vector3d<T>, crossProduct), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), "bool isBetweenPoints(const vector3df begin, const vector3df end) const", asMETHOD(core::vector3d<T>, isBetweenPoints), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), "vector3df& normalize()", asMETHOD(core::vector3d<T>, normalize), asCALL_THISCALL); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), "string toString()", asFUNCTION(toString<T>), asCALL_GENERIC); assert( r >= 0 );
}
template<typename T>
void static Vector3d_Generic(asIScriptEngine *engine, std::string name)
{
s32 r = 0;
std::string type = typeid(T).name();
// Register the type
r = engine->RegisterObjectType(name.c_str(), sizeof(core::vector3d<T>), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_CAK); assert( r >= 0 );
// Register the object properties
r = engine->RegisterObjectProperty(name.c_str(), (type + "x").c_str(), offsetof(core::vector3d<T>, X)); assert( r >= 0 );
r = engine->RegisterObjectProperty(name.c_str(), (type + "y").c_str(), offsetof(core::vector3d<T>, Y)); assert( r >= 0 );
r = engine->RegisterObjectProperty(name.c_str(), (type + "z").c_str(), offsetof(core::vector3d<T>, Z)); assert( r >= 0 );
// Register the constructors
r = engine->RegisterObjectBehaviour(name.c_str(), asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(Vector3dDefaultConstructor_Generic<T>), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectBehaviour(name.c_str(), asBEHAVE_CONSTRUCT, "void f(const vector3df &in)", asFUNCTION(Vector3dCopyConstructor_Generic<T>), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectBehaviour(name.c_str(), asBEHAVE_CONSTRUCT, ("void f(" + type +", "+ type +", "+ type + ")").c_str(), asFUNCTION(Vector3dInitConstructor_Generic<T>), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectBehaviour(name.c_str(), asBEHAVE_CONSTRUCT, ("void f(" + type +")").c_str(), asFUNCTION(Vector3dInit2Constructor_Generic<T>), asCALL_GENERIC); assert( r >= 0 );
// Register the operator overloads
r = engine->RegisterObjectMethod(name.c_str(), "vector3df &opAddAssign(const vector3df &in)", asFUNCTION(Vector3dAddAssign_Generic<T>), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), "vector3df &opSubAssign(const vector3df &in)", asFUNCTION(Vector3dSubAssign_Generic<T>), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), ("vector3df &opMulAssign(" + type +")").c_str(), asFUNCTION(Vector3dMulAssign_Generic<T>), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), ("vector3df &opDivAssign(" + type +")").c_str(), asFUNCTION(Vector3dDivAssign_Generic<T>), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), "bool &opEquals(const vector3df &in)", asFUNCTION(vector3dfEqualGeneric<T>), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), "bool opEquals(const vector3df &in) const", asFUNCTION(vector3dfEqualGeneric<T>), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), "vector3df opAdd(const vector3df &in) const", asFUNCTION(Vector3dAdd_Generic<T>), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), "vector3df opSub(const vector3df &in) const", asFUNCTION(Vector3dSub_Generic<T>), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), ("vector3df opMul(" + type +") const").c_str(), asFUNCTION(Vector3dMulFloat_Generic<T>), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), ("vector3df opDiv(" + type +") const").c_str(), asFUNCTION(Vector3dDivFloat_Generic<T>), asCALL_GENERIC); assert( r >= 0 );
// Register the object methods
r = engine->RegisterObjectMethod(name.c_str(), (type +" getLength() const").c_str(), asFUNCTION(getLength<T>), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), (type +" getLengthSQ() const").c_str(), asFUNCTION(getLengthSQ<T>), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), (type +" dotProduct(const vector3df &in) const").c_str(), asFUNCTION(dotProduct<T>), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), (type +" getDistanceFrom(const vector3df &in) const").c_str(), asFUNCTION(getDistanceFrom<T>), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), (type +" getDistanceFromSQ(const vector3df &in) const").c_str(), asFUNCTION(getDistanceFromSQ<T>), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), "vector3df crossProduct(const vector3df &in) const", asFUNCTION(crossProduct<T>), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), "bool isBetweenPoints(const vector3df begin, const vector3df end) const", asFUNCTION(isBetweenPoints<T>), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), "vector3df& normalize()", asFUNCTION(normalize<T>), asCALL_GENERIC); assert( r >= 0 );
r = engine->RegisterObjectMethod(name.c_str(), "string toString()", asFUNCTION(toString<T>), asCALL_GENERIC); assert( r >= 0 );
}
template<typename T>
void static Register(asIScriptEngine *engine, std::string name)
{
if(strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY"))
Vector3d_Generic<T>(engine, name);
else
Vector3d_Native<T>(engine, name);
}
};
END_AS_NAMESPACE
#endif
[/code]
usage:
Vector3d::Register<f32>(engine, "vector3df"); or
Vector3d::Register<s32>(engine, "vector3di");