Advertisement

Just starting with AngelScript. How do I define this type?

Started by September 05, 2023 11:28 AM
16 comments, last by StrikerTheHedgefox 1 year, 2 months ago

I'm just starting out with AngelScript, and I have this type:

template <typename T> struct vec2
{
    T x, y;

    inline bool operator==(vec2<T> const c) { return (x == c.x) & (y == c.y); }
    inline bool operator!=(vec2<T> const c) { return (x != c.x) | (y != c.y); }

    vec2<T> &operator+=(const vec2<T> rhs) { x += rhs.x; y += rhs.y; return *this; }
    vec2<T> &operator-=(const vec2<T> rhs) { x -= rhs.x; y -= rhs.y; return *this; }
    vec2<T> &operator*=(const vec2<T> rhs) { x *= rhs.x; y *= rhs.y; return *this; }

    const vec2<T> operator+(const vec2<T> rhs) const { return { (T)(x + rhs.x), (T)(y + rhs.y) }; }
    const vec2<T> operator-(const vec2<T> rhs) const { return { (T)(x - rhs.x), (T)(y - rhs.y) }; }
    const vec2<T> operator*(const vec2<T> rhs) const { return { (T)(x * rhs.x), (T)(y * rhs.y) }; }
};

It's declared like this in the program:

typedef struct vec2<int32_t> vec2_t;

What I want to know is, how do I add this type to AngelScript, so I can do something like this? (Hopefully including the operators)

void myFunc()
{
	vec2_t myVect;
	myVect.x = 10;
	myVect.y = 42;
	// Do something yada yada yada
}

None

As per the documentation, you would probably register it with asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<vec2_t>(). Then you can register operator overloads as methods (like opAdd, opMul, etc.).

Advertisement

Took me a while to figure out what I was doing wrong, but I figured it out on my own. Here's what I got:

    asEngine->RegisterObjectType("vec2_t", sizeof(vec2_t), asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<vec2_t>());
    asEngine->RegisterObjectProperty("vec2_t", "int32_t x", asOFFSET(vec2_t, x));
    asEngine->RegisterObjectProperty("vec2_t", "int32_t y", asOFFSET(vec2_t, y));
    asEngine->RegisterObjectMethod("vec2_t", "vec2_t opAddAssign(vec2_t)", asMETHODPR(vec2_t, operator+=, (const vec2_t), vec2_t&), asCALL_THISCALL);
    asEngine->RegisterObjectMethod("vec2_t", "vec2_t opSubAssign(vec2_t)", asMETHODPR(vec2_t, operator-=, (const vec2_t), vec2_t&), asCALL_THISCALL);
    asEngine->RegisterObjectMethod("vec2_t", "vec2_t opMulAssign(vec2_t)", asMETHODPR(vec2_t, operator*=, (const vec2_t), vec2_t&), asCALL_THISCALL);
    asEngine->RegisterObjectMethod("vec2_t", "vec2_t opAdd(vec2_t)", asMETHODPR(vec2_t, operator+, (const vec2_t) const, const vec2_t), asCALL_THISCALL);
    asEngine->RegisterObjectMethod("vec2_t", "vec2_t opSub(vec2_t)", asMETHODPR(vec2_t, operator-, (const vec2_t) const, const vec2_t), asCALL_THISCALL);
    asEngine->RegisterObjectMethod("vec2_t", "vec2_t opMul(vec2_t)", asMETHODPR(vec2_t, operator*, (const vec2_t) const, const vec2_t), asCALL_THISCALL);

Either way, thanks!

None

You may also want add the flag asOBJ_APP_CLASS_ALLINTS for vec2<int32_t> and other integer types, and asOBJ_APP_CLASS_ALLFLOATS for vec2<float> or vec2<double>.

This is necessary on some compilers and target platforms if you plan to pass the type by value to application registered functions (on other compilers and target platforms where it is not necessary the flag will be ignored).

Manual: https://angelcode.com/angelscript/sdk/docs/manual/doc_register_val_type.html

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

Now I have another problem. I have a pointer to a array of structs, and I need it accessible by index in Angelscript, like: `sprite[num].member`

Here's what I have. Obviously, this doesn't work, and the documentation is completely opaque in this regard, not providing any examples, and I can't find the information I need.
sprite is defined as uspritetype *sprite; in engine, which points towards this static array: uspritetype sprite_s[16384]; If you're wondering why it's set up like that instead of accessing sprite_s directly, is because sometimes the pointer needs to be changed to other related static arrays for various reasons.

    asEngine->RegisterObjectType("sprite_t", sizeof(uspritetype), asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<uspritetype>());
    asEngine->RegisterObjectProperty("sprite_t", "int32_t x", asOFFSET(uspritetype, x));
    asEngine->RegisterObjectProperty("sprite_t", "int32_t y", asOFFSET(uspritetype, y));
    asEngine->RegisterObjectProperty("sprite_t", "int32_t z", asOFFSET(uspritetype, z));
    asEngine->RegisterObjectProperty("sprite_t", "vec2_t xy", asOFFSET(uspritetype, xy));
    asEngine->RegisterObjectProperty("sprite_t", "vec3_t xyz", asOFFSET(uspritetype, xyz));
    asEngine->RegisterObjectProperty("sprite_t", "uint16_t cstat", asOFFSET(uspritetype, cstat));
    asEngine->RegisterObjectProperty("sprite_t", "int16_t picnum", asOFFSET(uspritetype, picnum));
    asEngine->RegisterObjectProperty("sprite_t", "int8_t shade", asOFFSET(uspritetype, shade));
    asEngine->RegisterObjectProperty("sprite_t", "uint8_t pal", asOFFSET(uspritetype, pal));
    asEngine->RegisterObjectProperty("sprite_t", "uint8_t clipdist", asOFFSET(uspritetype, clipdist));
    asEngine->RegisterObjectProperty("sprite_t", "uint8_t blend", asOFFSET(uspritetype, blend));
    asEngine->RegisterObjectProperty("sprite_t", "uint8_t xrepeat", asOFFSET(uspritetype, xrepeat));
    asEngine->RegisterObjectProperty("sprite_t", "uint8_t yrepeat", asOFFSET(uspritetype, yrepeat));
    asEngine->RegisterObjectProperty("sprite_t", "int8_t xoffset", asOFFSET(uspritetype, xoffset));
    asEngine->RegisterObjectProperty("sprite_t", "int8_t yoffset", asOFFSET(uspritetype, yoffset));
    asEngine->RegisterObjectProperty("sprite_t", "int16_t sectnum", asOFFSET(uspritetype, sectnum));
    asEngine->RegisterObjectProperty("sprite_t", "int16_t statnum", asOFFSET(uspritetype, statnum));
    asEngine->RegisterObjectProperty("sprite_t", "int16_t ang", asOFFSET(uspritetype, ang));
    asEngine->RegisterObjectProperty("sprite_t", "int16_t owner", asOFFSET(uspritetype, owner));
    asEngine->RegisterObjectProperty("sprite_t", "int16_t xvel", asOFFSET(uspritetype, xvel));
    asEngine->RegisterObjectProperty("sprite_t", "int16_t yvel", asOFFSET(uspritetype, yvel));
    asEngine->RegisterObjectProperty("sprite_t", "int16_t zvel", asOFFSET(uspritetype, zvel));
    asEngine->RegisterObjectProperty("sprite_t", "vec3_16_t vel", asOFFSET(uspritetype, vel));
    asEngine->RegisterObjectProperty("sprite_t", "int16_t lotag", asOFFSET(uspritetype, lotag));
    asEngine->RegisterObjectProperty("sprite_t", "int16_t hitag", asOFFSET(uspritetype, hitag));
    asEngine->RegisterObjectProperty("sprite_t", "int16_t extra", asOFFSET(uspritetype, extra));
    asEngine->RegisterGlobalProperty("sprite_t @sprite", &sprite);

None

Advertisement

You don't show much of your code so I can only guess.

Probably you'll be able to do something like this:

uspritetype &opIndex(asUINT idx, uspritetype *arr)
{
   return arr[idx];
}
engine->RegisterObjectMethod("arrayofsprites", “uspritetype &opIndex(uint idx)", asFUNCTION(opIndex), asCALL_CDECL_OBJLAST);

You should add proper checks on the idx to catch out of bounds scenarios and properly handle the error, but I hope you get the idea.

Obviously you'll need to register the "arrayofsprites" type as well to represent your array type.

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

@WitchLord So, arrayofsprites needs to be a separate type from the base struct type? (aka. sprite_t that I've defined)

None

Yes. The script language does not yet have support for simple C array structures (due to the difficulty to safely control the memory used).

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

Ah, hopefully someday that'll be a thing.

Anyway, when you do the above, will that also let me write to the values and have those reflect in the program? like: sprite[idx].picnum = 10;?

EDIT: Also, this look right?

    asEngine->RegisterObjectType("spritearray_t", 1, asOBJ_VALUE | asOBJ_POD);
    asEngine->RegisterObjectMethod("spritearray_t", "sprite_t &opIndex(uint32_t idx)", asFUNCTION(asOpIndex_sprite), asCALL_CDECL_OBJLAST);
    asEngine->RegisterGlobalProperty("spritearray_t sprite", &sprite);

None

This topic is closed to new replies.

Advertisement