Таким образом мы убиваем двух зайцев, имея высокую производительно там где подтип известен, и поддержку всех других типов, о которых мы не знаем заранее.
// Регистрация шаболна r = engine->RegisterObjectType("myTemplate" , 0, asOBJ_REF | asOBJ_GC | asOBJ_TEMPLATE); assert( r >= 0 );
Шаблонный тип по умолчанию не использует сборщика мусора, но если вы не знаете сколько обьектов породит шаблон, рекомендуется его подключить
Когда регистрируем отношения, методы и свойства для шаблонного типа, имя шаблонного типа состоит из имени шаблона и типа в угловых скобках, без слова class (myTemplate < Type >).
Имя типа должно совпадать с именем, обьявленным с помошью RegisterObjectType.
Отношения для шаблонов так же отличаются от обычной регистрации отношени.
Для получения созданног типа фабрика получает asIObjectType первым скрытым параметром.
При регистрации фабрики этот скрытый параметр отражен в декларации (int &in).
// Регистрация отношений r = engine->RegisterObjectBehaviour("myTemplate" , asBEHAVE_FACTORY, "myTemplate@ f(int&in)" , asFUNCTIONPR(myTemplateFactory, (asIObjectType*), myTemplate*), asCALL_CDECL); assert( r >= 0 );
Списочная фабрика регистрируется аналогично :
// Регистрация отношений списочной фабрики r = engine->RegisterObjectBehaviour("myTemplate" , asBEHAVE_LIST_FACTORY, "myTemplate@ f(int&in, uint)" , asFUNCTIONPR(myTemplateListFactory, (asIObjectType*, unsigned int), myTemplate*), asCALL_CDECL); assert( r >= 0 );
Помните, так как тип определяется в рантайме, не возможно обьявить функции для получения типа по значению, поэтому необходимо использовать ссылки. Как вариант - использовать хендлы, но тогда скриптовый движок не сможет использовать шаблон для типов-значений.
Каллбек должен быть глобальной функцией, которая принимает указатель на asIObjectType, и возвращает true в случае успеха.
// Регистрируем каллбек r = engine->RegisterObjectBehaviour("myTemplate" , asBEHAVE_TEMPLATE_CALLBACK, "bool f(int &in)", asFUNCTION(myTemplateCallback), asCALL_CDECL); assert( r >= 0 );
Вот функция каллбека:
bool myTemplateCallback(asIObjectType *ot) { // Этот шаблон поддерживает только примитивные типы int typeId = ot->GetSubTypeId(); if( typeId & asTYPEID_MASK_OBJECT ) { // Скрипт пытается создать экземляр шаблона с типом обьекта, это не допускается return false; } // Примитивные типы разрешены return true; }
Специализации шаблонов регистрируется следующим образом :
// Регистрируем специализацию для типа float r = engine->RegisterObjectType("myTemplate" , 0, asOBJ_REF); assert( r >= 0 ); // Регистрируем фабрику (нет скрытых параметров для специализации) r = engine->RegisterObjectBehaviour("myTemplate" , asBEHAVE_FACTORY, "myTemplate@ f()" , asFUNCTION(myTemplateFloatFactory, (), myTemplateFloat*), asCALL_CDECL); assert( r >= 0 );