#include "luabindings.hpp" #include #include "eventqueue.hpp" #include "luamanagerimp.hpp" namespace sol { template <> struct is_automagical : std::false_type {}; template <> struct is_automagical : std::false_type {}; template <> struct is_automagical : std::false_type {}; template <> struct is_automagical : std::false_type {}; } namespace MWLua { template static void registerObjectList(const std::string& prefix, const Context& context) { using ListT = ObjectList; sol::state& lua = context.mLua->sol(); ObjectRegistry* registry = context.mWorldView->getObjectRegistry(); sol::usertype listT = lua.new_usertype(prefix + "ObjectList"); listT[sol::meta_function::to_string] = [](const ListT& list) { return "{" + std::to_string(list.mIds->size()) + " objects}"; }; listT[sol::meta_function::length] = [](const ListT& list) { return list.mIds->size(); }; listT[sol::meta_function::index] = [registry](const ListT& list, size_t index) { if (index > 0 && index <= list.mIds->size()) return ObjectT((*list.mIds)[index - 1], registry); else throw std::runtime_error("Index out of range"); }; listT["ipairs"] = [registry](const ListT& list) { auto iter = [registry](const ListT& l, int64_t i) -> sol::optional> { if (i >= 0 && i < static_cast(l.mIds->size())) return std::make_tuple(i + 1, ObjectT((*l.mIds)[i], registry)); else return sol::nullopt; }; return std::make_tuple(iter, list, 0); }; } template static void addBasicBindings(sol::usertype& objectT, const Context& context) { objectT["isValid"] = [](const ObjectT& o) { return o.isValid(); }; objectT["recordId"] = sol::readonly_property([](const ObjectT& o) -> std::string { return o.ptr().getCellRef().getRefId(); }); objectT["position"] = sol::readonly_property([](const ObjectT& o) -> osg::Vec3f { return o.ptr().getRefData().getPosition().asVec3(); }); objectT["rotation"] = sol::readonly_property([](const ObjectT& o) -> osg::Vec3f { return o.ptr().getRefData().getPosition().asRotationVec3(); }); objectT["type"] = sol::readonly_property(&ObjectT::type); objectT[sol::meta_function::equal_to] = [](const ObjectT& a, const ObjectT& b) { return a.id() == b.id(); }; objectT[sol::meta_function::to_string] = &ObjectT::toString; objectT["sendEvent"] = [context](const ObjectT& dest, std::string eventName, const sol::object& eventData) { context.mLocalEventQueue->push_back({dest.id(), std::move(eventName), LuaUtil::serialize(eventData, context.mSerializer)}); }; if constexpr (std::is_same_v) { // Only for global scripts objectT["addScript"] = [luaManager=context.mLuaManager](const GObject& object, const std::string& path) { luaManager->addLocalScript(object.ptr(), path); }; } } template static void initObjectBindings(const std::string& prefix, const Context& context) { sol::usertype objectT = context.mLua->sol().new_usertype(prefix + "Object"); addBasicBindings(objectT, context); registerObjectList(prefix, context); } void initObjectBindingsForLocalScripts(const Context& context) { initObjectBindings("L", context); } void initObjectBindingsForGlobalScripts(const Context& context) { initObjectBindings("G", context); } }