Hello!
This is a follow-up of this issue: https://www.gamedev.net/forums/topic/712952-strange-behavior-when-registering-method-with-template-specialization-types/5450698/
The thread was closed because I didn't have time to work on the issue since I had to pause my scripting environment implementation. I went back working at it and I tried to understand the internals to see where the problem arises.
Just to recap what happens is that if I try to register 2 methods that return a specialized template type:
registerMethod("RecipeStep", "Slice<item::Stack> input()", CALL_METHOD_ARGS(RecipeStep, input, (void), DataSlice<ItemStack>), "");
registerMethod("RecipeStep", "Slice<item::Stack> output()", CALL_METHOD_ARGS(RecipeStep, output, (void), DataSlice<ItemStack>), "");
I get an error “Slice is not a template type”.
I debugged the implementation inside as_scriptengine.cpp and this is what happens:
First registration
asCBuilder::CreateDataTypeFromNode(asCScriptNode *node, asCScriptCode *file, asSNameSpace *implicitNamespace, bool acceptHandleForScope, asCObjectType *currentType, bool reportError, bool *isValid)
for return type is called- it loops through
engine→GetParentNameSpace(ns)
becauseRecipeStep
is indata
namespace - on second iteration
ti = GetType(str.AddressOf(), ns, parentType)
assign correct value - this branch is taken
if( ti->flags & asOBJ_TEMPLATE )
and everything works fine
Second registration
asCBuilder::CreateDataTypeFromNode(asCScriptNode *node, asCScriptCode *file, asSNameSpace *implicitNamespace, bool acceptHandleForScope, asCObjectType *currentType, bool reportError, bool *isValid)
for return type is called again- This time
ti = GetTypeFromTypesKnownByObject(str.AddressOf(), currentType);
returns aasCTypeInfo*
at first iteration (with different address than the previous one) - this branch is NOT taken
ti->flags & asOBJ_TEMPLATE
- method fails with
msg.Format(TXT_TYPE_s_NOT_TEMPLATE, ti->name.AddressOf());
I hope this can help you pinpoint the issue. Some additional details:
Slice
is registered in global namespace assizeof(void*), asOBJ_VALUE | asOBJ_TEMPLATE
Slice<item::Stack>
is registered assizeof(type_t), asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<DataSlice<T>>()
RecipeStep
is registered indata
namespace