Оглавление

Ваш первый скрипт

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

// Создаем движок
asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);

// Устанавливаем калбек для получения информации об ошибках
r = engine->SetMessageCallback(asFUNCTION(MessageCallback), 0, asCALL_CDECL); assert( r >= 0 );

// AngelScript не имеет встроенного типа для строки, так как нет определенного стандарта для С++.
// Но вы можете зарегистрировать собственную реализацию, либо воспользоваться строковыми типами, представленными в аддонах.
RegisterStdString(engine);

// Регистрируем функцию, которую будет вызывать скрипт.
r = engine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(print), asCALL_CDECL); assert( r >= 0 );

После настройки следующим шагом является компиляция скриптов, которые должны быть выполнены. Ниже наш скрипт, который будет вызывать зарегистрированную функцию, печатающую Hello World в стандартный поток вывода. Допустим скрипт хранится в файле test.as.

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

Вот код для загрузки файла скрипта и его компиляции:

// CScriptBuilder  из аддонов помогает загружать файлы, содержит препроцессор и собирает модули.
CScriptBuilder builder;
r = builder.BuildScriptFromFile(engine, "MyModule", "test.as");
if( r < 0 )
{
  // Произошла ошибка, информация о ней указана в выходном потоке.
  printf("Скрипт содержит ошибки, исправьте их.\n");
  return;
}

Последний шаг заключается в определении функции, которая будет вызываться, и создании контекса для выполнения:

// Находим функцию для вызова. 
asIScriptModule *mod = engine->GetModule("MyModule");
int funcId = mod->GetFunctionIdByDecl("void main()");
if( funcId < 0 )
{
  // Функция не найдена, скриптеру следует включить ее в скрипт.
  printf("Скрипт должен иметь функцию 'void main()'. Добавьте ее.\n");
  return;
}

// Создаем контекст, подготавливаем и запускаем.
asIScriptContext *ctx = engine->CreateContext();
ctx->Prepare(funcId);
r = ctx->Execute()
if( r != asEXECUTION_FINISHED )
{
  // Выполнение не закончилось как ожидалось, узнаем что случилось.
  if( r == asEXECUTION_EXCEPTION )
  {
    printf("Произошла '%s' ошибка. Проверьте код.\n", ctx->GetExceptionString());
  }
}

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

Не забывайте производить очистку после работы:

// Очищаем
ctx->Release();
engine->Release();

Вспомогательные функции

Простая обертка для функции печати:
// Выводит скриптовую строку в стандартный поток вывода.
void print(string &msg)
{
  printf("%s", msg.c_str());
}
Рекомендуется:
Сообщение обратного вызова, Сборщик скриптов, Строка(STL)

Перевод - arroy.one@gmail.com. При копировании материалов указывайте ссылку на источник.