diff options
Diffstat (limited to 'source/core/StarLuaConverters.hpp')
-rw-r--r-- | source/core/StarLuaConverters.hpp | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/source/core/StarLuaConverters.hpp b/source/core/StarLuaConverters.hpp new file mode 100644 index 0000000..bf030cd --- /dev/null +++ b/source/core/StarLuaConverters.hpp @@ -0,0 +1,264 @@ +#ifndef STAR_LUA_CONVERTERS_HPP +#define STAR_LUA_CONVERTERS_HPP + +#include "StarRect.hpp" +#include "StarVector.hpp" +#include "StarColor.hpp" +#include "StarPoly.hpp" +#include "StarLine.hpp" +#include "StarLua.hpp" +#include "StarVariant.hpp" + +namespace Star { + +template <typename T1, typename T2> +struct LuaConverter<pair<T1, T2>> { + static LuaValue from(LuaEngine& engine, pair<T1, T2>&& v) { + auto t = engine.createTable(); + t.set(1, move(v.first)); + t.set(2, move(v.second)); + return t; + } + + static LuaValue from(LuaEngine& engine, pair<T1, T2> const& v) { + auto t = engine.createTable(); + t.set(1, v.first); + t.set(2, v.second); + return t; + } + + static Maybe<pair<T1, T2>> to(LuaEngine& engine, LuaValue const& v) { + if (auto table = engine.luaMaybeTo<LuaTable>(move(v))) { + auto p1 = engine.luaMaybeTo<T1>(table->get(1)); + auto p2 = engine.luaMaybeTo<T2>(table->get(2)); + if (p1 && p2) + return {{p1.take(), p2.take()}}; + } + return {}; + } +}; + +template <typename T, size_t N> +struct LuaConverter<Vector<T, N>> { + static LuaValue from(LuaEngine& engine, Vector<T, N> const& v) { + return engine.createArrayTable(v); + } + + static Maybe<Vector<T, N>> to(LuaEngine& engine, LuaValue const& v) { + auto table = v.ptr<LuaTable>(); + if (!table) + return {}; + + Vector<T, N> vec; + for (size_t i = 0; i < N; ++i) { + auto v = engine.luaMaybeTo<T>(table->get(i + 1)); + if (!v) + return {}; + vec[i] = *v; + } + return vec; + } +}; + +template <typename T> +struct LuaConverter<Matrix3<T>> { + static LuaValue from(LuaEngine& engine, Matrix3<T> const& m) { + auto table = engine.createTable(); + table.set(1, luaFrom(engine, m.row1)); + table.set(2, luaFrom(engine, m.row2)); + table.set(3, luaFrom(engine, m.row3)); + return table; + } + + static Maybe<Matrix3<T>> to(LuaEngine& engine, LuaValue const& v) { + if (auto table = v.ptr<LuaTable>()) { + auto r1 = engine.luaMaybeTo<typename Matrix3<T>::Vec3>(table->get(1)); + auto r2 = engine.luaMaybeTo<typename Matrix3<T>::Vec3>(table->get(2)); + auto r3 = engine.luaMaybeTo<typename Matrix3<T>::Vec3>(table->get(3)); + if (r1 && r2 && r3) + return Matrix3<T>(*r1, *r2, *r3); + } + return {}; + } +}; + +template <typename T> +struct LuaConverter<Rect<T>> { + static LuaValue from(LuaEngine& engine, Rect<T> const& v) { + if (v.isNull()) + return LuaNil; + auto t = engine.createTable(); + t.set(1, v.xMin()); + t.set(2, v.yMin()); + t.set(3, v.xMax()); + t.set(4, v.yMax()); + return t; + } + + static Maybe<Rect<T>> to(LuaEngine& engine, LuaValue const& v) { + if (v == LuaNil) + return Rect<T>::null(); + + if (auto table = v.ptr<LuaTable>()) { + auto xMin = engine.luaMaybeTo<T>(table->get(1)); + auto yMin = engine.luaMaybeTo<T>(table->get(2)); + auto xMax = engine.luaMaybeTo<T>(table->get(3)); + auto yMax = engine.luaMaybeTo<T>(table->get(4)); + if (xMin && yMin && xMax && yMax) + return Rect<T>(*xMin, *yMin, *xMax, *yMax); + } + return {}; + } +}; + +template <typename T> +struct LuaConverter<Polygon<T>> { + static LuaValue from(LuaEngine& engine, Polygon<T> const& poly) { + return engine.createArrayTable(poly.vertexes()); + } + + static Maybe<Polygon<T>> to(LuaEngine& engine, LuaValue const& v) { + if (auto points = engine.luaMaybeTo<typename Polygon<T>::VertexList>(v)) + return Polygon<T>(points.take()); + return {}; + } +}; + +template <typename T, size_t N> +struct LuaConverter<Line<T, N>> { + static LuaValue from(LuaEngine& engine, Line<T, N> const& line) { + auto table = engine.createTable(); + table.set(1, line.min()); + table.set(2, line.max()); + return table; + } + + static Maybe<Line<T, N>> to(LuaEngine& engine, LuaValue const& v) { + if (auto table = v.ptr<LuaTable>()) { + auto min = engine.luaMaybeTo<Vector<T, N>>(table->get(1)); + auto max = engine.luaMaybeTo<Vector<T, N>>(table->get(2)); + if (min && max) + return Line<T, N>(*min, *max); + } + return {}; + } +}; + +// Sort of magical converter, tries to convert from all the types in the +// Variant in order, returning the first correct type. Types should not be +// ambiguous, or the more specific types should come first, which relies on the +// implementation of the converters. +template <typename FirstType, typename... RestTypes> +struct LuaConverter<Variant<FirstType, RestTypes...>> { + static LuaValue from(LuaEngine& engine, Variant<FirstType, RestTypes...> const& variant) { + return variant.call([&engine](auto const& a) { return luaFrom(engine, a); }); + } + + static LuaValue from(LuaEngine& engine, Variant<FirstType, RestTypes...>&& variant) { + return variant.call([&engine](auto& a) { return luaFrom(engine, move(a)); }); + } + + static Maybe<Variant<FirstType, RestTypes...>> to(LuaEngine& engine, LuaValue const& v) { + return checkTypeTo<FirstType, RestTypes...>(engine, v); + } + + template <typename CheckType1, typename CheckType2, typename... CheckTypeRest> + static Maybe<Variant<FirstType, RestTypes...>> checkTypeTo(LuaEngine& engine, LuaValue const& v) { + if (auto t1 = engine.luaMaybeTo<CheckType1>(v)) + return t1; + else + return checkTypeTo<CheckType2, CheckTypeRest...>(engine, v); + } + + template <typename Type> + static Maybe<Variant<FirstType, RestTypes...>> checkTypeTo(LuaEngine& engine, LuaValue const& v) { + return engine.luaMaybeTo<Type>(v); + } + + static Maybe<Variant<FirstType, RestTypes...>> to(LuaEngine& engine, LuaValue&& v) { + return checkTypeTo<FirstType, RestTypes...>(engine, move(v)); + } + + template <typename CheckType1, typename CheckType2, typename... CheckTypeRest> + static Maybe<Variant<FirstType, RestTypes...>> checkTypeTo(LuaEngine& engine, LuaValue&& v) { + if (auto t1 = engine.luaMaybeTo<CheckType1>(v)) + return t1; + else + return checkTypeTo<CheckType2, CheckTypeRest...>(engine, move(v)); + } + + template <typename Type> + static Maybe<Variant<FirstType, RestTypes...>> checkTypeTo(LuaEngine& engine, LuaValue&& v) { + return engine.luaMaybeTo<Type>(move(v)); + } +}; + +// Similarly to Variant converter, tries to convert from all types in order. +// An empty MVariant is converted to nil and vice versa. +template <typename... Types> +struct LuaConverter<MVariant<Types...>> { + static LuaValue from(LuaEngine& engine, MVariant<Types...> const& variant) { + LuaValue value; + variant.call([&value, &engine](auto const& a) { + value = luaFrom(engine, a); + }); + return value; + } + + static LuaValue from(LuaEngine& engine, MVariant<Types...>&& variant) { + LuaValue value; + variant.call([&value, &engine](auto& a) { + value = luaFrom(engine, move(a)); + }); + return value; + } + + static Maybe<MVariant<Types...>> to(LuaEngine& engine, LuaValue const& v) { + if (v == LuaNil) + return MVariant<Types...>(); + return checkTypeTo<Types...>(engine, v); + } + + template <typename CheckType1, typename CheckType2, typename... CheckTypeRest> + static Maybe<MVariant<Types...>> checkTypeTo(LuaEngine& engine, LuaValue const& v) { + if (auto t1 = engine.luaMaybeTo<CheckType1>(v)) + return t1; + else + return checkTypeTo<CheckType2, CheckTypeRest...>(engine, v); + } + + template <typename CheckType> + static Maybe<MVariant<Types...>> checkTypeTo(LuaEngine& engine, LuaValue const& v) { + return engine.luaMaybeTo<CheckType>(v); + } + + static Maybe<MVariant<Types...>> to(LuaEngine& engine, LuaValue&& v) { + if (v == LuaNil) + return MVariant<Types...>(); + return checkTypeTo<Types...>(engine, move(v)); + } + + template <typename CheckType1, typename CheckType2, typename... CheckTypeRest> + static Maybe<MVariant<Types...>> checkTypeTo(LuaEngine& engine, LuaValue&& v) { + if (auto t1 = engine.luaMaybeTo<CheckType1>(v)) + return t1; + else + return checkTypeTo<CheckType2, CheckTypeRest...>(engine, move(v)); + } + + template <typename CheckType> + static Maybe<MVariant<Types...>> checkTypeTo(LuaEngine& engine, LuaValue&& v) { + return engine.luaMaybeTo<CheckType>(move(v)); + } + +}; + +template <> +struct LuaConverter<Color> { + static LuaValue from(LuaEngine& engine, Color const& c); + static Maybe<Color> to(LuaEngine& engine, LuaValue const& v); +}; + +} + +#endif |