Будучи встроенной библиотекой, 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()); } }
Обработка исключений очень проста. Приложение может также получить информацию о номерах строк, функции, стек вызовов, и даже значений локальных и глобальных переменных, если захочет.
Не забывайте производить очистку после работы:
// Выводит скриптовую строку в стандартный поток вывода. void print(string &msg) { printf("%s", msg.c_str()); }