AngelScript

Описание: Разработка и отладка приложений. Упор на 3D-графику.

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#1 dyvniy » Ср, 22 января 2014, 09:16:06

Хорошая штука, давно на неё глаз положил.
Прекрасное дополнение в прогремме на С++, если какую-то функциональность надо постоянно менять, править и модифицировать.
http://www.angelcode.com/
http://stackoverflow.com/questions/tagged/angelscript
http://13d-labs.com/angelscript_manual/main.html
Изображение
http://www.pvsm.ru/programmirovanie/13577
http://www.wasm.ru/forum/viewtopic.php?id=44374
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#2 dyvniy » Пн, 8 сентября 2014, 22:39:17

http://www.gamedev.ru/code/articles/AngelScript
Спойлер
В данной статье мне хотелось бы показать почему мне понравился скриптовый язык AngelScript. Когда я выбирал язык для своего движка, я просмотрел множество кандидатур, и для подробного рассмотрения выбрал два скриптовых языка, ими были LUA и Python.

Введение.
Превью.
Особенности.
Проблемы.
Регистрация перегруженных функций.
Регистрация перегруженных методов.
Получения адреса на переменную объявленную в классе.
Полезные ссылки.

Введение.
В процессе рассмотрения LUA и Python я выделил для себя, что LUA является достаточно быстрым, но с немного непривычным синтаксисом. Python же обладает очень простым синтаксисом и массой полезных библиотек, но, к сожалению, он оказался довольно медленным, и его довольно тяжело привязывать к С++. И тут на работе мне подсказали использовать AngelScript, мол, он удобный для связки, быстрее LUA и имеет С-подобный синтаксис. Как только я начал его изучать, я понял, что это тот самый скриптовый язык моей мечты.

aslogo | AngelScript

Превью.
Вот что можно прочитать про этот язык на Википедии:

AngelScript представляет собой движок, в котором приложение может регистрировать функции, свойства и типы, которые могут использоваться в скриптах. Скрипты компилируются в модули. Количество используемых модулей варьрируется в зависимости от нужд. Приложение может также использовать различные интерфейсы для каждого модуля с помощью групп конфигурации. Это особенно полезно, когда приложение работает с несколькими типами скриптов, например, GUI, AI и т.д.

Программа «Hello, world» в простейшем случае выглядит так:

void main()
{
print("Hello world\n");
}
Да, синтаксис языка радует с самого начала. Язык поддерживает как методы функционального программирования, так и ООП. С самого начала он подкупает своей простотой регистрации функций, переменных, типов.

Например, регистрация глобальной переменной:

g_Engine->RegisterGlobalProperty("int SomeVal",&SomeVal);
где SomeVal — это переменная типа int.
Регистрация глобальной функции:

g_Engine->RegisterGlobalFunction("void Print(string val)",
asFUNCTION(Print), asCALL_CDECL);

void Print(string val)
{
cout<<val.data();
}
Да, для AngelScript не нужно писать функции биндинга, что является огроменным плюсом в сравнении с другими языками. Для регистрации своих типов придётся написать парочку функций. Фабрику для создания экземпляров и счётчик ссылок, для типа Тип-ссылка, и вызовы конструктора и деструктора, для объекта типа Тип-значение.

Например, у нас есть класс float3, который мы хотели бы зарегистрировать.

// класс счётчик ссылок
class RefC
{
private:
int refC;
public:
RefC(){refC=1;}
void AddRef(){refC++;}
void Release()
{
if(!--refC)
delete this;
}
};

// Класс, который мы хотим зарегистрировать
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()
{
return new float3();
}

// Функция вывода на экран
void PrintF3(float3* val)
{
cout<<"x="<<val->x<<",y="<<val->y<<",z="<<val->z;
}
Для этого мы регистрируем объект как Тип-ссылка и указываем ему фабрику, счётчик ссылок, метод и функцию вывода данных на экран, и вот как это выглядит.

g_Engine->RegisterObjectType("float3",0,asOBJ_REF);

g_Engine->RegisterObjectMethod("float3"," void Normalize()",asMETHOD(float3, Normalize),asCALL_THISCALL);
g_Engine->RegisterObjectBehaviour("float3",asBEHAVE_FACTORY,"float3@ new_float3()",asFUNCTION(Float3FactoryE),asCALL_CDECL);
g_Engine->RegisterObjectBehaviour("float3",asBEHAVE_ADDREF,"void AddRef()",asMETHOD(float3,AddRef),asCALL_THISCALL);
g_Engine->RegisterObjectBehaviour("float3",asBEHAVE_RELEASE,"void Release()",asMETHOD(float3,Release),asCALL_THISCALL);

g_Engine->RegisterGlobalFunction("void Print(float3@ val)",asFUNCTION(PrintF3),asCALL_CDECL);

Мы на этом конечно же не остановимся, так как нам нужен доступ к значениям xyz, поэтому их мы тоже должны зарегистрировать, что мы и делаем написав.

g_Engine->RegisterObjectProperty("float3","float x",offsetof(float3,x));
g_Engine->RegisterObjectProperty("float3","float y",offsetof(float3,y));
g_Engine->RegisterObjectProperty("float3","float z",offsetof(float3,z));
Всё предельно просто и понятно. Теперь в скрипте можно написать

float3@ ObjPos;
ObjPos.x=1;
ObjPos.y=2;
ObjPos.z=3;

ObjPos.Normalize();
Print( ObjPos );
Выполнив этот скрипт, мы увидим на экране значение нормализованного вектора.

Особенности.
Меня очень порадовала возможность перегрузки операторов в AngelScript. В С++ для это существует ключевое слово operator и символ оператора. AngelScript для этого использует определённые функции. Вот полный список соответствий.

♦ – opNeg
♦ ~ opCom
♦ ++ opPreInc
♦ -- opPreDec
♦ ++ opPostInc
♦ -- opPostDec
♦ == opEquals
♦ != opEquals
♦ < opCmp
♦ <= opCmp
♦ > opCmp
♦ >= opCmp
♦ = opAssign
♦ += opAddAssign
♦ -= opSubAssign
♦ *= opMulAssign
♦ /= opDivAssign
♦ &= opAndAssign
♦ |= opOrAssign
♦ ^= opXorAssign
♦ %= opModAssign
♦ <<= opShlAssign
♦ >>= opShrAssign
♦ >>>= opUShrAssign
♦ + opAdd opAdd_r
♦ - opSub opSub_r
♦ * opMul opMul_r
♦ / opDiv opDiv_r
♦ % opMod opMod_r
♦ & opAnd opAnd_r
♦ | opOr opOr_r
♦ ^ opXor opXor_r
♦ << opShl opShl_r
♦ >> opShr opShr_r
♦ >>> opUShr opUShr_r
♦ [] opIndex

Допустим, мы хотим сделать возможность, чтобы наш вектор поддерживал прибавление к себе другого вектора, для этого слегка модифицируем наш класс.

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* operator+=(float3* _rval)
{
x+=_rval->x;
y+=_rval->y;
z+=_rval->z;
this->AddRef();
return this;
}
};
Осталось только зарегистрированный новый метод.

g_Engine->RegisterObjectMethod("float3", "float3@ opAddAssign(float3@ _rval)",
asMETHOD(float3, operator+=), asCALL_THISCALL);
И теперь можно спокойно писать так:

float3@ ObjPos;
ObjPos.x=1;
ObjPos.y=2;
ObjPos.z=3;

float3@ ObjOffset;
ObjOffset .x=3;
ObjOffset .y=1;
ObjOffset .z=5;

ObjPos+=ObjOffset ;
Print( ObjPos );
и мы увидим на экране x=4, y=3, z=8.
AngelScript поддерживает свойства. Выглядит это так:

class MyObj
{
type get_ValueName();
type set_ValueName(type Val);
}
MyObj a;
type tmp=a.ValueName;// вызовется get_ValueName
a.ValueName = tmp; // вызовется set_ValueName
Также свойства поддерживаются для оператора индекса:

class MyObj
{
float get_opIndex(int idx) ;
void set_opIndex(int idx, float value);
}
MyObj a;
float val=a[1];// вызовется get_opIndex
a[2]=val;// вызовется set_opIndex
Проблемы.
Во время изучения языка AngelScript, появилось несколько проблем, решение которых отняло у меня довольно много времени. Вот список проблем, о которых я хотел бы рассказать:
♦ Регистрация перегруженных функций.
♦ Регистрация перегруженных методов.
♦ Получения адреса на переменную объявленную в классе.

Регистрация перегруженных функций.
Очень часто возникает необходимость объявить перегруженную функцию для удобства чтения и понимания кода.
Например:

void Print(string val)
{
cout<<val.data();
}

void Print(int val)
{
cout<<val;
}

void Print(float val)
{
cout<<val;
}

void Print(float3* val)
{
cout<<"x="<<val->x<<",y="<<val->y<<",z="<<val->z;
}
Обычная регистрация вызовет ошибку.

g_Engine->RegisterGlobalFunction("void Print(string val)",
asFUNCTION(Print), asCALL_CDECL); // Ошибка
Так как компилятор не понимает адрес какой из четырёх функций нужно передать, то на ум приходит два решения:
♦ Создать typedef нужной функции и осуществить приведение типов.
♦ Создать переменную указатель на нужную функцию и передать его.

вот как выглядит второе решение:

void (*PrintS)(string val)=&Print;
void (*PrintI)(int val)=&Print;
void (*PritnF)(float val)=&Print;
void (*PrintF3)(float3* val)=&Print;

g_Engine->RegisterGlobalFunction("void Print(string val)",asFUNCTION(PrintS),asCALL_CDECL);
g_Engine->RegisterGlobalFunction("void Print(int val)",asFUNCTION(PrintI),asCALL_CDECL);
g_Engine->RegisterGlobalFunction("void Print(float val)",asFUNCTION(PritnF),asCALL_CDECL);
g_Engine->RegisterGlobalFunction("void Print(float3@ val)",asFUNCTION(PrintF3),asCALL_CDECL);
Регистрация перегруженных методов.
С данной проблемой вы столкнётесь, если захотите зарегистрировать оператор присваивания. Давайте для примера модифицируем наш класс.

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* operator+=(float3* _rval)
{
x+=_rval->x;
y+=_rval->y;
z+=_rval->z;
this->AddRef();
return this;
}

float3* operator=(float3* _rval)
{
x=_rval->x;
y=_rval->y;
z=_rval->z;
this->AddRef();
return this;
}
};
Обычная регистрация вызовет ошибку.

g_Engine->RegisterObjectMethod("float3", "float3@ opAssign(float3@ _rval)",
asMETHOD(float3, operator=), asCALL_THISCALL); // Ошибка
Решения, которые подходят для функций, тут не подойдут. Для решения проблемы надо внимательно взглянуть на макрос asMETHOD он выглядит так:

#define asMETHOD(c,m) asSMethodPtr::Convert((void (c::*)())(&c::m))
Соответственно, чтобы нам зарегистрировать метод, нужно конвертировать его. Тогда наша регистрация будет выглядеть так:

g_Engine->RegisterObjectMethod("float3", "float3@ opAssign(float3@ _rval)",
asSMethodPtr::Convert((float3* (float3::*)(float3*))(&float3::operator=)),
asCALL_THISCALL);
Получения адреса на переменную объявленную в классе.
Если с глобальными переменными дела обстоят предельно просто, то с переменными в пределах класса всё немного сложнее. Стандартные средства не позволяют получить ID переменной по её имени или объявлению, поэтому для этого необходимо пройтись по всем переменным в классе самому и сравнить имена. Для поиска адреса по имени переменной нам потребуется само имя и указатель на экземпляр класса скрипта.

Функция будет выглядеть так:

void* GetPropAddress(const char* Name,asIScriptObject* ScriptObject)
{
for(int i=0;iGetPropertyCount();i++)
if(!strcmp(ScriptObject->GetPropertyName(i),Name))
return ScriptObject->GetAddressOfProperty(i);
return 0;
}
Вот и всё, что мне хотелось бы рассказать, да я не осветил моменты касающиеся JIT и Шаблонов, но это только потому, что ещё не разбирался с этим. По мере изучения буду обновлять статью.
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#3 dyvniy » Вт, 3 января 2017, 12:48:19

Говорят быстрее луа и точно понятней питона.
https://habrahabr.ru/post/145340/
Спойлер
Разработка → AngelScript из песочницы
Программирование*, C++*
Введение

В процессе рассмотрения LUA и Python я выделил для себя, что LUA является достаточно быстрым, но с немного непривычным синтаксисом. Python же обладает очень простым синтаксисом и массой полезных библиотек, но, к сожалению, он оказался довольно медленным, и его довольно тяжело привязывать к С++. И тут на работе мне подсказали использовать AngelScript, мол, он удобный для связки, быстрее LUA и имеет С-подобный синтаксис. Как только я начал его изучать, я понял, что это тот самый скриптовый язык моей мечты.

Превью

Вот что можно прочитать про этот язык на Википедии:

AngelScript представляет собой движок, в котором приложение может регистрировать функции, свойства и типы, которые могут использоваться в скриптах. Скрипты компилируются в модули. Количество используемых модулей варьрируется в зависимости от нужд. Приложение может также использовать различные интерфейсы для каждого модуля с помощью групп конфигурации. Это особенно полезно, когда приложение работает с несколькими типами скриптов, например, GUI, AI и т.д.

Программа «Hello, world» в простейшем случае выглядит так:

void main()
{
print("Hello world\n");
}


Да, синтаксис языка радует с самого начала. Язык поддерживает как методы функционального программирования, так и ООП. С самого начала он подкупает своей простотой регистрации функций, переменных, типов.

Например, регистрация глобальной переменной:

g_Engine->RegisterGlobalProperty("int SomeVal",&SomeVal);


где SomeVal — это переменная типа int.

Регистрация глобальной функции:
g_Engine->RegisterGlobalFunction("void Print(string val)",
asFUNCTION(Print), asCALL_CDECL);

void Print(string val)
{
cout<<val.data();
}


Да, для AngelScript не нужно писать функции биндинга, что является огроменным плюсом в сравнении с другими языками. Для регистрации своих типов придётся написать парочку функций. Фабрику для создания экземпляров и счётчик ссылок, для типа Тип-ссылка, и вызовы конструктора и деструктора, для объекта типа Тип-значение.

Например, у нас есть класс float3, который мы хотели бы зарегистрировать.

// класс счётчик ссылок
class RefC
{
private:
int refC;
public:
RefC(){refC=1;}
void AddRef(){refC++;}
void Release()
{
if(!--refC)
delete this;
}
};

// Класс, который мы хотим зарегистрировать
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()
{
return new float3();
}

// Функция вывода на экран
void PrintF3(float3* val)
{
cout<<"x="<<val->x<<",y="<<val->y<<",z="<<val->z;
}


Для этого мы регистрируем объект как Тип-ссылка и указываем ему фабрику, счётчик ссылок, метод и функцию вывода данных на экран, и вот как это выглядит.

g_Engine->RegisterObjectType("float3",0,asOBJ_REF);

g_Engine->RegisterObjectMethod("float3"," void Normalize()",asMETHOD(float3, Normalize),asCALL_THISCALL);
g_Engine->RegisterObjectBehaviour("float3",asBEHAVE_FACTORY,"float3@ new_float3()",asFUNCTION(Float3FactoryE),asCALL_CDECL);
g_Engine->RegisterObjectBehaviour("float3",asBEHAVE_ADDREF,"void AddRef()",asMETHOD(float3,AddRef),asCALL_THISCALL);
g_Engine->RegisterObjectBehaviour("float3",asBEHAVE_RELEASE,"void Release()",asMETHOD(float3,Release),asCALL_THISCALL);

g_Engine->RegisterGlobalFunction("void Print(float3@ val)",asFUNCTION(PrintF3),asCALL_CDECL);


Мы на этом конечно же не остановимся, так как нам нужен доступ к значениям xyz, поэтому их мы тоже должны зарегистрировать, что мы и делаем написав.
g_Engine->RegisterObjectProperty("float3","float x",offsetof(float3,x));
g_Engine->RegisterObjectProperty("float3","float y",offsetof(float3,y));
g_Engine->RegisterObjectProperty("float3","float z",offsetof(float3,z));


Всё предельно просто и понятно. Теперь в скрипте можно написать
float3@ ObjPos;
ObjPos.x=1;
ObjPos.y=2;
ObjPos.z=3;

ObjPos.Normalize();
Print( ObjPos );


Выполнив этот скрипт, мы увидим на экране значение нормализованного вектора.

Особенности


Меня очень порадовала возможность перегрузки операторов в AngelScript. В С++ для это существует ключевое слово operator и символ оператора. AngelScript для этого использует определённые функции.

¦ – opNeg
¦ ~ opCom
¦ ++ opPreInc
¦ — opPreDec
¦ ++ opPostInc
¦ — opPostDec
¦ == opEquals
¦ != opEquals
¦ < opCmp
¦ <= opCmp
¦ > opCmp
¦ >= opCmp
¦ = opAssign
¦ += opAddAssign
¦ -= opSubAssign
¦ *= opMulAssign
¦ /= opDivAssign
¦ &= opAndAssign
¦ |= opOrAssign
¦ ^= opXorAssign
¦ %= opModAssign
¦ <<= opShlAssign
¦ >>= opShrAssign
¦ >>>= opUShrAssign
¦ + opAdd opAdd_r
¦ — opSub opSub_r
¦ * opMul opMul_r
¦ / opDiv opDiv_r
¦ % opMod opMod_r
¦ & opAnd opAnd_r
¦ | opOr opOr_r
¦ ^ opXor opXor_r
¦ << opShl opShl_r
¦ >> opShr opShr_r
¦ >>> opUShr opUShr_r
¦ [] opIndex

Допустим, мы хотим сделать возможность, чтобы наш вектор поддерживал прибавление к себе другого вектора, для этого слегка модифицируем наш класс.

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* operator+=(float3* _rval)
{
x+=_rval->x;
y+=_rval->y;
z+=_rval->z;
this->AddRef();
return this;
}
};


Осталось только зарегистрированный новый метод.
g_Engine->RegisterObjectMethod("float3", "float3@ opAddAssign(float3@ _rval)",
asMETHOD(float3, operator+=), asCALL_THISCALL);


И теперь можно спокойно писать так:

float3@ ObjPos;
ObjPos.x=1;
ObjPos.y=2;
ObjPos.z=3;

float3@ ObjOffset;
ObjOffset .x=3;
ObjOffset .y=1;
ObjOffset .z=5;

ObjPos+=ObjOffset ;
Print( ObjPos );

и мы увидим на экране x=4, y=3, z=8.

AngelScript поддерживает свойства. Выглядит это так:
class MyObj
{
type get_ValueName();
type set_ValueName(type Val);
}
MyObj a;
type tmp=a.ValueName;// вызовется get_ValueName
a.ValueName = tmp; // вызовется set_ValueName


Также свойства поддерживаются для оператора индекса:
class MyObj
{
float get_opIndex(int idx) ;
void set_opIndex(int idx, float value);
}
MyObj a;
float val=a[1];// вызовется get_opIndex
a[2]=val;// вызовется set_opIndex


Полезные ссылки

Сайт разработчиков www.angelcode.com
SVN Репозиторий на WIP angelscript.svn.sourceforge.net/svnroot/angelscript/trunk
Русский мануал 13d-labs.com/angelscript_manual/main.html
Мануал на английском www.angelcode.com/angelscript/sdk/docs/manual/index.html
JIT Компилятор github.com/BlindMindStudios/AngelScript-JIT-Compiler
AngelScript, scripts, C++, скриптовые языки, впечатления
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама
Хабы
Программирование
Проектирование и рефакторинг
Open source
Системы сборки
Семантика
Системы управления версиями
Анализ и проектирование систем
Git
XML
PHP
Все хабы
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама
+7
7,5k
68


Гиляровский Константин @Chaos_Optima карма
8,0
рейтинг0,0
Пользователь
Похожие публикации
+17
Подходы к созданию скриптового языка описания настольных игр 17,2k 157 29
+17
Создание игры на ваших глазах — часть 3: Прикручиваем скриптовый язык к Unity (UniLua) 34,6k 264 35
+14
Groovy как скриптовый язык и DSL для Java 12,9k 46 3
Самое читаемое Разработка
Сейчас Сутки Неделя Месяц
+36
Писать веб-сайты на ассемблере полезно и приятно 13,6k 81 48
+81
Как проектируют ненастоящие программисты 26k 76 143
+7
Обзор self-hosted continuous integration систем 1,9k 18 1
+47
Самые востребованные языки программирования 2016 48,9k 96 125
+46
Информационные технологии в новогоднем мюзикле «Чародеи» 9,6k 12 31
Комментарии (17)

alexyr 22 августа 2012 в 17:31 0
Воспользуйтесь тегом <сode>, читать будет легче!
Mithgol 22 августа 2012 в 17:39 +14
Воспользуйтесь тегом <source>…</source>, читать будет ещё легче!
coll3ctor 22 августа 2012 в 22:31 –3
воспользуйтесь этим… тэгом и будет ещё лучше!
define_rak 22 августа 2012 в 23:13 0
А если еще использовать перенос строк и отступы то будет совсем идеально.
coll3ctor 22 августа 2012 в 23:41 0
Извините, уважаемый хабр съел мой тег. Короче: добавьте ещё в тег lang=«cpp» и всё будет совсем клёво!
А по сабжу: статья хорошая, было интересно, но есть малюсенький минус: где это использовать? для чего и как? А прежде всего: зачем?
Буду рад услышать ответы на эти вопросы. Да даже, если и не услышу, я ужерад!
Chaos_Optima 24 августа 2012 в 14:56 0
Спасибо за замечания, поправил.
Используется это для того чтобы часть логики своего приложения можно было вывести за пределы исходного кода, как это уже другой вопрос. Скриптовые движки активно используются в играх.
Vass 22 августа 2012 в 17:41 0
Лучше тегом source
moadib 22 августа 2012 в 19:47 0
Почувствовал едва уловимое дежавю от вступления, а Ваша статья была на gamedev.ru, оказывается :)

Интересно, эта информация еще актуальна? Мне всегда импанировали AngelScript и Squirrel, но lua всегда может чем-то ответить своим конкурентам :)

Monnoroch 22 августа 2012 в 20:15 0
Перегрузка операторов из D, любопытно.
НЛО прилетело и опубликовало эту надпись здесь
Mezomish 23 августа 2012 в 04:43 +3
Смотрим сюда: www.gamedev.ru/code/articles/AngelScript

А теперь сюда: habrahabr.ru/info/help/rules/
Хабр — не ЖЖ и не центр мирового кросспостинга. Не нужно копировать посты из других блогов и сайтов, указывая, что ранее они были опубликованы в другом месте.
moadib 23 августа 2012 в 07:27 +1
Строго говоря, он ведь не нарушил правило :) Т.к. не указывал, что эта статья ранее была опубликована на gamedev.ru ;)
Mezomish 23 августа 2012 в 07:29 0
Сильно подозреваю, что кросспостить не указывая оригинал — ещё хуже :)
Chaos_Optima 24 августа 2012 в 15:01 0
Ну я же репост своей статьи делал, так что не думаю что я нарушил правила.
Mezomish 24 августа 2012 в 17:40 0
В правилах не уточняется насчёт «своих» или «чужих». Значит любых.
igrishaev 23 августа 2012 в 05:31 +1
Не хочу холивара, но Си-подобный синтаксис — очень спорная штука, записывать ее в плюсы не стоит.
Лично мне, наоборот, отсутствие точек с запятой и фигурных скобок помогает сконцентрироваться на самой задаче, а не средствах ее реализации.
Chaos_Optima 24 августа 2012 в 15:02 0
Я отнёс это в плюс в основном потому что, если скорость работы скрипта не будет удовлетворять, то код скрипта можно будет вынести с минимальными изменениями.
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#4 dyvniy » Пн, 20 февраля 2017, 17:37:43

Надо к нему попробовать вернуться.
Или нормально интегрировать в программу питон, посмотрим.
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#5 dyvniy » Пн, 17 апреля 2017, 10:14:45

Distionaries
http://www.angelcode.com/angelscript/sdk/docs/manual/doc_datatypes_dictionary.html
Dictionaries are only available in the scripts if the application registers the support for them. The syntax for using dictionaries may differ for the application you're working with so consult the application's manual for more details.
Спойлер
The dictionary stores key-value pairs, where the key is a string, and the value can be of any type. Key-value pairs can be added or removed dynamically, making the dictionary a good general purpose container object.

obj object;
obj @handle;
// Initialize with a list
dictionary dict = {{'one', 1}, {'object', object}, {'handle', @handle}};
// Examine and access the values through get or set methods ...
if( dict.exists('one') )
{
// get returns true if the stored type is compatible with the requested type
bool isValid = dict.get('handle', @handle);
if( isValid )
{
dict.delete('object');
dict.set('value', 1);
}
}
Dictionary values can also be accessed or added by using the index operator.

// Read and modify an integer value
int val = int(dict['value']);
dict['value'] = val + 1;
// Read and modify a handle to an object instance
@handle = cast<obj>(dict['handle']);
if( handle is null )
@dict['handle'] = object;
Dictionaries can also be created and initialized within expressions as anonymous objects.

// Call a function that expects a dictionary as input
foo(dictionary = {{'a', 1},{'b', 2}});
Dictionaries of dictionaries are created using anonymous objects as well.

dictionary d2 = {{'a', dictionary = {{'aa', 1}, {'ab', 2}}},
{'b', dictionary = {{'ba', 1}, {'bb', 2}}}};
Supporting dictionary object and functions

The dictionary object is a reference type, so it's possible to use handles to the dictionary object when passing it around to avoid costly copies.

Operators

= assignment
The assignment operator performs a shallow copy of the content.

[] index operator
The index operator takes a string for the key, and returns a reference to the value. If the key/value pair doesn't exist it will be inserted with a null value.

Methods

void set(const string &in key, ? &in value)
void set(const string &in key, int64 &in value)
void set(const string &in key, double &in value)
Sets a key/value pair in the dictionary. If the key already exists, the value will be changed.

bool get(const string &in key, ? &out value) const
bool get(const string &in key, int64 &out value) const
bool get(const string &in key, double &out value) const
Retrieves the value corresponding to the key. The methods return false if the key is not found, and in this case the value will maintain its default value based on the type.

array<string> @getKeys() const
This method returns an array with all of the existing keys in the dictionary. The order of the keys in the array is undefined.

bool exists(const string &in key) const
Returns true if the key exists in the dictionary.

bool delete(const string &in key)
Removes the key and the corresponding value from the dictionary. Returns false if the key wasn't found.

void deleteAll()
Removes all entries in the dictionary.

bool isEmpty() const
Returns true if the dictionary doesn't hold any entries.

uint getSize() const
Returns the number of keys in the dictionary.

Supporting dictionaryValue object and functions

The dictionaryValue type is how the dictionary object stores the values. When accessing the values through the dictionary index operator a reference to a dictionaryValue is returned.

The dictionaryValue type itself is a value type, i.e. no handles to it can be held, but it can hold handles to other objects as well as values of any type.

Operators

= assignment
The value assignment operator should be used to copy a value into the dictionaryValue.

@= handle assignment
The handle assignment operator should be used to set the dictionaryValue to refer to an object instance.

cast<type> cast operator
The cast operator is used to dynamically cast the handle held in the dictionaryValue to the desired type. If the dictionaryValue doesn't hold a handle, or the handle is not compatible with the desired type, the cast operator will return a null handle.

type() conversion operator
The conversion operator is used to return a new value of the desired type. If no value conversion is found, an uninitialized value of the desired type is returned.
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#6 dyvniy » Пн, 17 апреля 2017, 14:13:48

Прям хочу!
Только телефон за 35 - это пока слишком.
http://www.mvideo.ru/products/smartfon-honor-8-pr ... duk-l09-30027686/specification
Изображение


Название раздела: Программирование (под Desktop и Android)
Описание: Разработка и отладка приложений. Упор на 3D-графику.

Быстрый ответ


Введите код в точности так, как вы его видите. Регистр символов не имеет значения.
Код подтверждения
:) ;) :hihi: :P :hah: :haha: :angel: :( :st: :_( :cool: 8-| :beee: :ham: :rrr: :grr: :* :secret: :stupid: :music: Ещё смайлики…
   

Вернуться в «Программирование (под Desktop и Android)»

Кто сейчас на форуме (по активности за 15 минут)

Сейчас этот раздел просматривают: 9 гостей