Внешние библиотеки в haxe

Разрабатывая игру для дефолда на haxe в какой-то момент потребуется использовать внешние библиотеки дефолда. Очевидно что в хаксе нет api для работы с этими библиотеками. Как же получить доступ к дополнительным возможностям?

Untyped

Для начала в хаксе есть ключевое слово untyped. С его помощью можно писать код, который игнорирует систему типов. Для примера возьмем такую библиотеку на луа:

local M = {

}

M.sum = function(a, b) return a + b end

return M

Что бы вызвать такой модуль из хакса можно написать следующий код:

var module = untyped require("module");
var c = untyped module.sum(1, 2);
trace(c);

Этот код успешно скомпилируется и отработает, но тут не будет ни какой проверки типов потому не рекомендую им пользоваться.

Extern

Правильный способ – написать extern-класс для вашей библиотеки:

@:luaRequire("main")
extern class Module {
	static function sum(a: Int, b: Int): Int; 
}

Как вы заметили, я использовал ключевое слово extern и не указываю тело функции – это сигнал компилятору, что функция определена извне. Так же указана аннотация luaRequire эта часть специфичная для lua, она указывает из какого файла сделать require.

В случае lua, класс может не требовать require а сразу быть доступным извне. Например это касается стандартных классов os\sys\io\math... В случае os можно создать такой класс:

@:native("os")
extern class Os {
	@:native("new")
	static function new_(code: Int): Void
}

Поскольку модуль называется с маленькой буквы, а хакс требует называть классы с прописной, я явно указываю имя класса как os (можно еще указать _G.os). Так же я указал native для функции new. Так нужно в случае, когда функция называется так же как ключевое слово haxe.

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

@:native("vmath")
extern class VMath {
	@:overload(function(a: Vector, b: Vector):Vector {})
	static function sum(a: Int, b: Int): Int;
} 

Тут описана функция sum, которая умеет складывать как вектора так и числа.

Еще одна фишка lua – возврат нескольких значений из функции. В хаксе для этого предусмотрена аннотация multiReturn. Вот пример из документации:

@:native("string")
extern class NativeString {
    public static function find(str : String, target : String): StringFind;
}

@:multiReturn extern class StringFind {
    var begin : Int;
    var end : Int;
}

Таким образом хакс позволяет быстро и легко подключать внещние библиотеки и использовать всю мощь типизации.