mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-28 12:40:06 +00:00
Don't expose LuaUtil::Callback to lua
This commit is contained in:
parent
71ba7b88e2
commit
65885d994f
@ -115,9 +115,9 @@ namespace MWLua
|
|||||||
MWBase::Environment::get().getWorld()->castRenderingRay(res, from, to, false, false);
|
MWBase::Environment::get().getWorld()->castRenderingRay(res, from, to, false, false);
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
api["asyncCastRenderingRay"] = [context](const LuaUtil::Callback& callback, const osg::Vec3f& from,
|
api["asyncCastRenderingRay"] = [context](
|
||||||
const osg::Vec3f& to) {
|
const sol::table& callback, const osg::Vec3f& from, const osg::Vec3f& to) {
|
||||||
context.mLuaManager->addAction([context, callback, from, to] {
|
context.mLuaManager->addAction([context, callback = LuaUtil::Callback::fromLua(callback), from, to] {
|
||||||
MWPhysics::RayCastingResult res;
|
MWPhysics::RayCastingResult res;
|
||||||
MWBase::Environment::get().getWorld()->castRenderingRay(res, from, to, false, false);
|
MWBase::Environment::get().getWorld()->castRenderingRay(res, from, to, false, false);
|
||||||
context.mLuaManager->queueCallback(callback, sol::main_object(context.mLua->sol(), sol::in_place, res));
|
context.mLuaManager->queueCallback(callback, sol::main_object(context.mLua->sol(), sol::in_place, res));
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include <gmock/gmock.h>
|
#include <gmock/gmock.h>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <components/lua/scriptscontainer.hpp>
|
#include <components/lua/asyncpackage.hpp>
|
||||||
#include <components/lua/storage.hpp>
|
#include <components/lua/storage.hpp>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@ -24,15 +24,16 @@ namespace
|
|||||||
LuaUtil::LuaStorage storage(mLua);
|
LuaUtil::LuaStorage storage(mLua);
|
||||||
|
|
||||||
std::vector<std::string> callbackCalls;
|
std::vector<std::string> callbackCalls;
|
||||||
LuaUtil::Callback callback{ sol::make_object(mLua,
|
sol::table callbackHiddenData(mLua, sol::create);
|
||||||
[&](const std::string& section, const sol::optional<std::string>& key) {
|
callbackHiddenData[LuaUtil::ScriptsContainer::sScriptIdKey] = LuaUtil::ScriptId{};
|
||||||
|
sol::table callback(mLua, sol::create);
|
||||||
|
callback[1] = [&](const std::string& section, const sol::optional<std::string>& key) {
|
||||||
if (key)
|
if (key)
|
||||||
callbackCalls.push_back(section + "_" + *key);
|
callbackCalls.push_back(section + "_" + *key);
|
||||||
else
|
else
|
||||||
callbackCalls.push_back(section + "_*");
|
callbackCalls.push_back(section + "_*");
|
||||||
}),
|
};
|
||||||
sol::table(mLua, sol::create) };
|
callback[2] = LuaUtil::AsyncPackageId{ nullptr, 0, callbackHiddenData };
|
||||||
callback.mHiddenData[LuaUtil::ScriptsContainer::sScriptIdKey] = LuaUtil::ScriptId{};
|
|
||||||
|
|
||||||
mLua["mutable"] = storage.getMutableSection("test");
|
mLua["mutable"] = storage.getMutableSection("test");
|
||||||
mLua["ro"] = storage.getReadOnlySection("test");
|
mLua["ro"] = storage.getReadOnlySection("test");
|
||||||
|
@ -22,6 +22,21 @@ namespace LuaUtil
|
|||||||
std::string mName;
|
std::string mName;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Callback Callback::fromLua(const sol::table& t)
|
||||||
|
{
|
||||||
|
return Callback{ t.raw_get<sol::main_protected_function>(1), t.raw_get<AsyncPackageId>(2).mHiddenData };
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Callback::isLuaCallback(const sol::object& t)
|
||||||
|
{
|
||||||
|
if (!t.is<sol::table>())
|
||||||
|
return false;
|
||||||
|
sol::object meta = sol::table(t)[sol::metatable_key];
|
||||||
|
if (!meta.is<sol::table>())
|
||||||
|
return false;
|
||||||
|
return sol::table(meta).raw_get_or<bool, std::string_view, bool>("isCallback", false);
|
||||||
|
}
|
||||||
|
|
||||||
sol::function getAsyncPackageInitializer(
|
sol::function getAsyncPackageInitializer(
|
||||||
lua_State* L, std::function<double()> simulationTimeFn, std::function<double()> gameTimeFn)
|
lua_State* L, std::function<double()> simulationTimeFn, std::function<double()> gameTimeFn)
|
||||||
{
|
{
|
||||||
@ -53,13 +68,20 @@ namespace LuaUtil
|
|||||||
asyncId.mContainer->setupUnsavableTimer(
|
asyncId.mContainer->setupUnsavableTimer(
|
||||||
TimerType::GAME_TIME, gameTimeFn() + delay, asyncId.mScriptId, std::move(callback));
|
TimerType::GAME_TIME, gameTimeFn() + delay, asyncId.mScriptId, std::move(callback));
|
||||||
};
|
};
|
||||||
api["callback"] = [](const AsyncPackageId& asyncId, sol::main_protected_function fn) -> Callback {
|
|
||||||
return Callback{ std::move(fn), asyncId.mHiddenData };
|
|
||||||
};
|
|
||||||
|
|
||||||
sol::usertype<Callback> callbackType = lua.new_usertype<Callback>("Callback");
|
sol::table callbackMeta = sol::table::create(L);
|
||||||
callbackType[sol::meta_function::call]
|
callbackMeta[sol::meta_function::call] = [](const sol::table& callback, sol::variadic_args va) {
|
||||||
= [](const Callback& callback, sol::variadic_args va) { return callback.call(sol::as_args(va)); };
|
return Callback::fromLua(callback).call(sol::as_args(va));
|
||||||
|
};
|
||||||
|
callbackMeta[sol::meta_function::to_string] = [] { return "Callback"; };
|
||||||
|
callbackMeta[sol::meta_function::metatable] = false;
|
||||||
|
callbackMeta["isCallback"] = true;
|
||||||
|
api["callback"] = [callbackMeta](const AsyncPackageId& asyncId, sol::main_protected_function fn) -> sol::table {
|
||||||
|
sol::table c = sol::table::create(fn.lua_state(), 2);
|
||||||
|
c.raw_set(1, std::move(fn), 2, asyncId);
|
||||||
|
c[sol::metatable_key] = callbackMeta;
|
||||||
|
return c;
|
||||||
|
};
|
||||||
|
|
||||||
auto initializer = [](sol::table hiddenData) {
|
auto initializer = [](sol::table hiddenData) {
|
||||||
ScriptId id = hiddenData[ScriptsContainer::sScriptIdKey];
|
ScriptId id = hiddenData[ScriptsContainer::sScriptIdKey];
|
||||||
|
@ -22,6 +22,9 @@ namespace LuaUtil
|
|||||||
sol::main_protected_function mFunc;
|
sol::main_protected_function mFunc;
|
||||||
sol::table mHiddenData; // same object as Script::mHiddenData in ScriptsContainer
|
sol::table mHiddenData; // same object as Script::mHiddenData in ScriptsContainer
|
||||||
|
|
||||||
|
static bool isLuaCallback(const sol::object&);
|
||||||
|
static Callback fromLua(const sol::table&);
|
||||||
|
|
||||||
bool isValid() const { return mHiddenData[ScriptsContainer::sScriptIdKey] != sol::nil; }
|
bool isValid() const { return mHiddenData[ScriptsContainer::sScriptIdKey] != sol::nil; }
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
|
@ -111,7 +111,7 @@ namespace LuaUtil
|
|||||||
return section.mSection->get(key).getCopy(s);
|
return section.mSection->get(key).getCopy(s);
|
||||||
};
|
};
|
||||||
sview["asTable"] = [](const SectionView& section) { return section.mSection->asTable(); };
|
sview["asTable"] = [](const SectionView& section) { return section.mSection->asTable(); };
|
||||||
sview["subscribe"] = [](const SectionView& section, const Callback& callback) {
|
sview["subscribe"] = [](const SectionView& section, const sol::table& callback) {
|
||||||
std::vector<Callback>& callbacks = section.mSection->mCallbacks;
|
std::vector<Callback>& callbacks = section.mSection->mCallbacks;
|
||||||
if (!callbacks.empty() && callbacks.size() == callbacks.capacity())
|
if (!callbacks.empty() && callbacks.size() == callbacks.capacity())
|
||||||
{
|
{
|
||||||
@ -119,7 +119,7 @@ namespace LuaUtil
|
|||||||
std::remove_if(callbacks.begin(), callbacks.end(), [&](const Callback& c) { return !c.isValid(); }),
|
std::remove_if(callbacks.begin(), callbacks.end(), [&](const Callback& c) { return !c.isValid(); }),
|
||||||
callbacks.end());
|
callbacks.end());
|
||||||
}
|
}
|
||||||
callbacks.push_back(callback);
|
callbacks.push_back(Callback::fromLua(callback));
|
||||||
};
|
};
|
||||||
sview["reset"] = [](const SectionView& section, const sol::optional<sol::table>& newValues) {
|
sview["reset"] = [](const SectionView& section, const sol::optional<sol::table>& newValues) {
|
||||||
if (section.mReadOnly)
|
if (section.mReadOnly)
|
||||||
|
@ -106,11 +106,11 @@ namespace LuaUi
|
|||||||
throw std::logic_error("The \"events\" layout field must be a table of callbacks");
|
throw std::logic_error("The \"events\" layout field must be a table of callbacks");
|
||||||
auto events = eventsObj.as<sol::table>();
|
auto events = eventsObj.as<sol::table>();
|
||||||
events.for_each([ext](const sol::object& name, const sol::object& callback) {
|
events.for_each([ext](const sol::object& name, const sol::object& callback) {
|
||||||
if (name.is<std::string>() && callback.is<LuaUtil::Callback>())
|
if (name.is<std::string>() && LuaUtil::Callback::isLuaCallback(callback))
|
||||||
ext->setCallback(name.as<std::string>(), callback.as<LuaUtil::Callback>());
|
ext->setCallback(name.as<std::string>(), LuaUtil::Callback::fromLua(callback));
|
||||||
else if (!name.is<std::string>())
|
else if (!name.is<std::string>())
|
||||||
Log(Debug::Warning) << "UI event key must be a string";
|
Log(Debug::Warning) << "UI event key must be a string";
|
||||||
else if (!callback.is<LuaUtil::Callback>())
|
else
|
||||||
Log(Debug::Warning) << "UI event handler for key \"" << name.as<std::string>()
|
Log(Debug::Warning) << "UI event handler for key \"" << name.as<std::string>()
|
||||||
<< "\" must be an openmw.async.callback";
|
<< "\" must be an openmw.async.callback";
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user