Описанные тут принципы используются в нескольких функциях, таких как RegisterGlobalFunction, RegisterObjectMethod, RegisterObjectBehaviour, RegisterGlobalBehaviour, и т.д..
Макрос asFUNCTION принимает имя функции как параметр, который работает для всех глобальных функций и не может быть перегружен. Если вы хотите использовать перегруженную функцию с одним и тем же именем, но с разными параметрами, вам пригодиться макрос asFUNCTIONPR. Он принимает в качестве параметра имя функции, список параметров и возвращаемый тип, так что компилятор C++ может определить какая функция перегружена, чтобы вернуть ее адрес.
// Глобальная функция void globalFunc(); r = engine->RegisterGlobalFunction("void globalFunc()", asFUNCTION(globalFunc), asCALL_CDECL); assert( r >= 0 ); // Перегруженная глобальная функция void globalFunc2(int); void globalFunc2(float); r = engine->RegisterGlobalFunction("void globalFunc2(int)", asFUNCTIONPR(globalFunc2, (int), void), asCALL_CDECL); assert( r >= 0 );
Аналогично работают asMETHOD/asMETHODPR. Отличия от asFUNCTION/asFUNCTIONPR заключаются в том, что методам необходимо дополнительно указывать имя класса, к которому они принадлежат.
class Object { // Метод класса void method(); // Перегруженный оператор присваивания Object &operator=(const Object &); Object &operator=(int); // Перегруженный метод void method2(int input); void method2(int input, int &output); // Константный метод int getAttr(int) const; }; // Регистрируем метод класса r = engine->RegisterObjectMethod("object", "void method()", asMETHOD(Object,method), asCALL_THISCALL); assert( r >= 0 ); // Регистрируем оператор присваивания r = engine->RegisterObjectBehaviour("object", asBEHAVE_ASSIGNMENT, "object &f(const object &in)", asMETHODPR(Object, operator=, (const Object&), Object&), asCALL_THISCALL); assert( r >= 0 ); r = engine->RegisterObjectBehaviour("object", asBEHAVE_ASSIGNMENT, "object &f(int)", asMETHODPR(Object, operator=, (int), Object&), asCALL_THISCALL); assert( r >= 0 ); // Регистрируем перегруженный метод r = engine->RegisterObjectMethod("object", "void method2(int)", asMETHODPR(Object, method2, (int), void), asCALL_THISCALL); assert( r >= 0 ); r = engine->RegisterObjectMethod("object", "void method2(int, int &out)", asMETHODPR(Object, method2, (int, int&), void), asCALL_THISCALL); assert( r >= 0 ); // Регистрируем константный метод r = engine->RegisterObjectMethod("object", "int getAttr(int) const", asMETHODPR(Object, getAttr, (int) const, int), asCALL_THISCALL); assert( r >= 0 );
class A { void SomeMethodA(); }; class B : virtual A {}; class C : virtual A {}; class D : public B, public C {}; // Требуется прокси-функция для регистрации метода SomeMethodA класса D void D_SomeMethodA_proxy(D *d) { // Компилятор C++ определит виртуальный метод для нас d->SomeMethodA(); } // Регистрируем глобальную функцию как метод класса, но используя asCALL_CDECL_OBJLAST engine->RegisterObjectMethod("D", "void SomeMethodA()", asFUNCTION(D_SomeMethodA_proxy), asCALL_CDECL_OBJLAST);
Если у вас есть много классов с виртуальным наследстванием, вам стоит подумать о написании шаблонов для прокси-функций, что вам не пришлось вручную писать все функции.
Все примитивные типы С++ соответствуют типам AngelScript, хотя иногда отличаются названием, например char в C++, но int8 в AngelScript.
Вы можете увидеть список всех типов и их соответствие тут.
Указатели не существуют в AngelScript в таком виде, как в C++, поэтому необходимо решить, как их передавать. Для этого у вас есть два варианта, лиюо как ссылку, либо как хендл. Большинство используемых указателей на объекты, представленные в виде ссылок\хендлов, легко обрабатываеются в AngelScript, но для некоторых необходимо написать более простой интерфейс, чтобы враппер справился.
Параметры ссылки в AngelScript имеют дополнительные ограничения.
Вы должны указать предполагаемый тип параметра - входной\выходной, или сразу и тот и другой.
Это делается с помощью ключей in, out, inout после &.
Если ключ не указа, AngelScript подставит ключ inout автоматически.
Типы значений могут быть только in и out, так как AngelScript не может гарантировать безопасность ссылок на них.
Хендлы - указатели на обьект с подсчетом ссылок, поэтому используя их обращайте внимание на механизм подсчета ссылок, методы создания и удаления обьекта.
Если вы не готовы сами следить за подсчетом ссылок, используйте автохендл (@+).
Строки тут немного сложнее, чем на C++, так как нет стандарта их реализации, поэтому AngelScript предлагает вам пару оберток (в аддонах).