В данной статье мне хотелось бы показать почему мне понравился скриптовый язык AngelScript. Когда я выбирал язык для своего движка, я просмотрел множество кандидатур, и для подробного рассмотрения выбрал два скриптовых языка, ими были LUA и Python.
В процессе рассмотрения LUA и Python я выделил для себя, что LUA является достаточно быстрым, но с немного непривычным синтаксисом. Python же обладает очень простым синтаксисом и массой полезных библиотек, но, к сожалению, он оказался довольно медленным, и его довольно тяжело привязывать к С++. И тут на работе мне подсказали использовать AngelScript, мол, он удобный для связки, быстрее LUA и имеет С-подобный синтаксис. Как только я начал его изучать, я понял, что это тот самый скриптовый язык моей мечты.
Превью.
Вот что можно прочитать про этот язык на Википедии:
AngelScript представляет собой движок, в котором приложение может регистрировать функции, свойства и типы, которые могут использоваться в скриптах. Скрипты компилируются в модули. Количество используемых модулей варьрируется в зависимости от нужд. Приложение может также использовать различные интерфейсы для каждого модуля с помощью групп конфигурации. Это особенно полезно, когда приложение работает с несколькими типами скриптов, например, GUI, AI и т.д.
Программа «Hello, world» в простейшем случае выглядит так:
void main()
{
print("Hello world\n");
}
Да, синтаксис языка радует с самого начала. Язык поддерживает как методы функционального программирования, так и ООП. С самого начала он подкупает своей простотой регистрации функций, переменных, типов.
Да, для AngelScript не нужно писать функции биндинга, что является огроменным плюсом в сравнении с другими языками. Для регистрации своих типов придётся написать парочку функций. Фабрику для создания экземпляров и счётчик ссылок, для типа Тип-ссылка, и вызовы конструктора и деструктора, для объекта типа Тип-значение.
Например, у нас есть класс float3, который мы хотели бы зарегистрировать.
// класс счётчик ссылокclass RefC
{
private:
int refC;
public:
RefC(){refC=1;}
void AddRef(){refC++;}
void Release()
{
if(!--refC)deletethis;
}
};
// Класс, который мы хотим зарегистрировать class float3:public RefC
{
public:
float x;
float y;
float z;
float3(){x=y=z=0;}
void Normalize()
{
float Len=sqrt(x*x+y*y+z*z);
Len=Len?Len:1;
x/=Len;
y/=Len;
z/=Len;
}
}
// Фабрика
float3* Float3FactoryE()
{
returnnew float3();
}
// Функция вывода на экранvoid PrintF3(float3* val)
{
cout<<"x="<<val->x<<",y="<<val->y<<",z="<<val->z;
}
Для этого мы регистрируем объект как Тип-ссылка и указываем ему фабрику, счётчик ссылок, метод и функцию вывода данных на экран, и вот как это выглядит.
Выполнив этот скрипт, мы увидим на экране значение нормализованного вектора.
Особенности.
Меня очень порадовала возможность перегрузки операторов в AngelScript. В С++ для это существует ключевое слово operator и символ оператора. AngelScript для этого использует определённые функции. Вот полный список соответствий.
Во время изучения языка AngelScript, появилось несколько проблем, решение которых отняло у меня довольно много времени. Вот список проблем, о которых я хотел бы рассказать:
♦ Регистрация перегруженных функций.
♦ Регистрация перегруженных методов.
♦ Получения адреса на переменную объявленную в классе.
Регистрация перегруженных функций.
Очень часто возникает необходимость объявить перегруженную функцию для удобства чтения и понимания кода.
Например:
Так как компилятор не понимает адрес какой из четырёх функций нужно передать, то на ум приходит два решения:
♦ Создать typedef нужной функции и осуществить приведение типов.
♦ Создать переменную указатель на нужную функцию и передать его.
Получения адреса на переменную объявленную в классе.
Если с глобальными переменными дела обстоят предельно просто, то с переменными в пределах класса всё немного сложнее. Стандартные средства не позволяют получить ID переменной по её имени или объявлению, поэтому для этого необходимо пройтись по всем переменным в классе самому и сравнить имена. Для поиска адреса по имени переменной нам потребуется само имя и указатель на экземпляр класса скрипта.
Вот и всё, что мне хотелось бы рассказать, да я не осветил моменты касающиеся JIT и Шаблонов, но это только потому, что ещё не разбирался с этим. По мере изучения буду обновлять статью.