Advertisement

Callback with templated parameter for method of a template class?

Started by September 11, 2024 07:07 AM
5 comments, last by WitchLord 3 months, 2 weeks ago

I'm trying to implement a for_each method for my personal script array, but I don't know how to properly write its declaration for RegisterObjectMethod. I have tried to write declaration like void for_each(void (const T&in)@ fn) or void for_each(void(@)(const T&in)) but it didn't work.

My current workaround is to register it as void for_each(?&in) and then handle the type information inside a wrapper. But my implementation has some problem. It can only accept a normal function. Once I pass a delegate, it explodes with segfault.

Link to my code for the wrapper

So my question is 1. how to register a templated funcdef, or 2. if a templated funcdef is not supported, how to write a function with ?&in parameter that handles the input correctly?

None

Update:

It seems that the cause of my second question is that my wrapper need to check for asTYPEID_OBJHANDLE and then dereference the pointer twice (*(void**)ptr).

Additional question: is there any document clarifying when to dereference pointer for the second time in C++ side?

None

Advertisement

You can register funcdefs as part of your template.

It looks like I've overlooked documenting this in the manual. But you can see it in practice on the scriptarray add-on and the sort method that takes a funcdef.

	// Sort with callback for comparison
	r = engine->RegisterFuncdef("bool array<T>::less(const T&in if_handle_then_const a, const T&in if_handle_then_const b)");
	r = engine->RegisterObjectMethod("array<T>", "void sort(const less &in, uint startAt = 0, uint count = uint(-1))", asMETHODPR(CScriptArray, Sort, (asIScriptFunction*, asUINT, asUINT), void), asCALL_THISCALL); assert(r >= 0);

As for the second question. The structure of the typeid is explained here: https://angelcode.com/angelscript/sdk/docs/manual/doc_typeid.html

I'll take your questions as a cue to improve the manual around these topics.

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

I encountered a strange issue. Once I registered a funcdef inside my custom array, the script using array<string> begin to crash. Those scripts and custom string worked fine before a funcdef registered. I can confirm this by using git reset.

I debugged into the code and found after registering the funcdef of array<T>, the constructor of my custom string wasn't properly called.

EDIT:

After debugging, I found a more precise cause. Once I registered a funcdef, the ti->GetSubTypeId() & asOBJ_REF now evaluates to true, which make my list factory of array<T> jump into wrong branch for construction. My custom string class is registered as a value type.

EDIT 2:

Sorry. It seems that I have made some silly mistakes. I mixed up type id and flags in a same variable.

None

@WitchLord So can you add an API like RegisterObjectFuncdef(const char* name, const char* decl) in the future version? After that, the code can be written as RegisterObjectFuncdef("array<T>", “void somefuncdef()”), which is much clearer. If nested typedef is also supported, a RegisterObjectTypedef(const char* name, const char* type, const char* decl) can be added as well.

Besides, it can make it easier to implement a template register helper like the one I'm currently working on (current solution is parsing the funcdef string and insert the class-name:: in front of the funcdef name).

None

I'll consider it.

Perhaps instead of adding another method to the interface, I can add an optional parameter “childOf” to RegisterFuncDef instead.

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

This topic is closed to new replies.

Advertisement