#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 struct LuaConverter> { static LuaValue from(LuaEngine& engine, pair&& 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 const& v) { auto t = engine.createTable(); t.set(1, v.first); t.set(2, v.second); return t; } static Maybe> to(LuaEngine& engine, LuaValue const& v) { if (auto table = engine.luaMaybeTo(move(v))) { auto p1 = engine.luaMaybeTo(table->get(1)); auto p2 = engine.luaMaybeTo(table->get(2)); if (p1 && p2) return {{p1.take(), p2.take()}}; } return {}; } }; template struct LuaConverter> { static LuaValue from(LuaEngine& engine, Vector const& v) { return engine.createArrayTable(v); } static Maybe> to(LuaEngine& engine, LuaValue const& v) { auto table = v.ptr(); if (!table) return {}; Vector vec; for (size_t i = 0; i < N; ++i) { auto v = engine.luaMaybeTo(table->get(i + 1)); if (!v) return {}; vec[i] = *v; } return vec; } }; template struct LuaConverter> { static LuaValue from(LuaEngine& engine, Matrix3 const& m) { auto table = engine.createTable(3, 0); table.set(1, m[0]); table.set(2, m[1]); table.set(3, m[2]); return table; } static Maybe> to(LuaEngine& engine, LuaValue const& v) { if (auto table = v.ptr()) { auto r1 = engine.luaMaybeTo::Vec3>(table->get(1)); auto r2 = engine.luaMaybeTo::Vec3>(table->get(2)); auto r3 = engine.luaMaybeTo::Vec3>(table->get(3)); if (r1 && r2 && r3) return Matrix3(*r1, *r2, *r3); } return {}; } }; template struct LuaConverter> { static LuaValue from(LuaEngine& engine, Rect 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> to(LuaEngine& engine, LuaValue const& v) { if (v == LuaNil) return Rect::null(); if (auto table = v.ptr()) { auto xMin = engine.luaMaybeTo(table->get(1)); auto yMin = engine.luaMaybeTo(table->get(2)); auto xMax = engine.luaMaybeTo(table->get(3)); auto yMax = engine.luaMaybeTo(table->get(4)); if (xMin && yMin && xMax && yMax) return Rect(*xMin, *yMin, *xMax, *yMax); } return {}; } }; template struct LuaConverter> { static LuaValue from(LuaEngine& engine, Polygon const& poly) { return engine.createArrayTable(poly.vertexes()); } static Maybe> to(LuaEngine& engine, LuaValue const& v) { if (auto points = engine.luaMaybeTo::VertexList>(v)) return Polygon(points.take()); return {}; } }; template struct LuaConverter> { static LuaValue from(LuaEngine& engine, Line const& line) { auto table = engine.createTable(); table.set(1, line.min()); table.set(2, line.max()); return table; } static Maybe> to(LuaEngine& engine, LuaValue const& v) { if (auto table = v.ptr()) { auto min = engine.luaMaybeTo>(table->get(1)); auto max = engine.luaMaybeTo>(table->get(2)); if (min && max) return Line(*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 struct LuaConverter> { static LuaValue from(LuaEngine& engine, Variant const& variant) { return variant.call([&engine](auto const& a) { return luaFrom(engine, a); }); } static LuaValue from(LuaEngine& engine, Variant&& variant) { return variant.call([&engine](auto& a) { return luaFrom(engine, move(a)); }); } static Maybe> to(LuaEngine& engine, LuaValue const& v) { return checkTypeTo(engine, v); } template static Maybe> checkTypeTo(LuaEngine& engine, LuaValue const& v) { if (auto t1 = engine.luaMaybeTo(v)) return t1; else return checkTypeTo(engine, v); } template static Maybe> checkTypeTo(LuaEngine& engine, LuaValue const& v) { return engine.luaMaybeTo(v); } static Maybe> to(LuaEngine& engine, LuaValue&& v) { return checkTypeTo(engine, move(v)); } template static Maybe> checkTypeTo(LuaEngine& engine, LuaValue&& v) { if (auto t1 = engine.luaMaybeTo(v)) return t1; else return checkTypeTo(engine, move(v)); } template static Maybe> checkTypeTo(LuaEngine& engine, LuaValue&& v) { return engine.luaMaybeTo(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 struct LuaConverter> { static LuaValue from(LuaEngine& engine, MVariant const& variant) { LuaValue value; variant.call([&value, &engine](auto const& a) { value = luaFrom(engine, a); }); return value; } static LuaValue from(LuaEngine& engine, MVariant&& variant) { LuaValue value; variant.call([&value, &engine](auto& a) { value = luaFrom(engine, move(a)); }); return value; } static Maybe> to(LuaEngine& engine, LuaValue const& v) { if (v == LuaNil) return MVariant(); return checkTypeTo(engine, v); } template static Maybe> checkTypeTo(LuaEngine& engine, LuaValue const& v) { if (auto t1 = engine.luaMaybeTo(v)) return t1; else return checkTypeTo(engine, v); } template static Maybe> checkTypeTo(LuaEngine& engine, LuaValue const& v) { return engine.luaMaybeTo(v); } static Maybe> to(LuaEngine& engine, LuaValue&& v) { if (v == LuaNil) return MVariant(); return checkTypeTo(engine, move(v)); } template static Maybe> checkTypeTo(LuaEngine& engine, LuaValue&& v) { if (auto t1 = engine.luaMaybeTo(v)) return t1; else return checkTypeTo(engine, move(v)); } template static Maybe> checkTypeTo(LuaEngine& engine, LuaValue&& v) { return engine.luaMaybeTo(move(v)); } }; template <> struct LuaConverter { static LuaValue from(LuaEngine& engine, Color const& c); static Maybe to(LuaEngine& engine, LuaValue const& v); }; } #endif