Move asyncpackage from apps/openmw/mwlua to components/lua

pull/3229/head
Petr Mikheev 2 years ago
parent 9673f5b932
commit 71ba7b88e2

@ -60,7 +60,7 @@ add_openmw_dir (mwscript
add_openmw_dir (mwlua add_openmw_dir (mwlua
luamanagerimp object worldview userdataserializer eventqueue luamanagerimp object worldview userdataserializer eventqueue
luabindings localscripts playerscripts objectbindings cellbindings asyncbindings luabindings localscripts playerscripts objectbindings cellbindings
camerabindings uibindings inputbindings nearbybindings postprocessingbindings stats debugbindings camerabindings uibindings inputbindings nearbybindings postprocessingbindings stats debugbindings
types/types types/door types/actor types/container types/weapon types/npc types/creature types/activator types/book types/lockpick types/probe types/apparatus types/potion types/ingredient types/misc types/repair types/armor types/light types/static types/clothing types/types types/door types/actor types/container types/weapon types/npc types/creature types/activator types/book types/lockpick types/probe types/apparatus types/potion types/ingredient types/misc types/repair types/armor types/light types/static types/clothing
worker worker

@ -1,72 +0,0 @@
#include "luabindings.hpp"
#include "worldview.hpp"
namespace sol
{
template <>
struct is_automagical<MWLua::AsyncPackageId> : std::false_type
{
};
template <>
struct is_automagical<LuaUtil::Callback> : std::false_type
{
};
}
namespace MWLua
{
struct TimerCallback
{
AsyncPackageId mAsyncId;
std::string mName;
};
sol::function getAsyncPackageInitializer(const Context& context)
{
using TimerType = LuaUtil::ScriptsContainer::TimerType;
sol::usertype<AsyncPackageId> api = context.mLua->sol().new_usertype<AsyncPackageId>("AsyncPackage");
api["registerTimerCallback"]
= [](const AsyncPackageId& asyncId, std::string_view name, sol::main_protected_function callback) {
asyncId.mContainer->registerTimerCallback(asyncId.mScriptId, name, std::move(callback));
return TimerCallback{ asyncId, std::string(name) };
};
api["newSimulationTimer"] = [world = context.mWorldView](const AsyncPackageId&, double delay,
const TimerCallback& callback, sol::main_object callbackArg) {
callback.mAsyncId.mContainer->setupSerializableTimer(TimerType::SIMULATION_TIME,
world->getSimulationTime() + delay, callback.mAsyncId.mScriptId, callback.mName,
std::move(callbackArg));
};
api["newGameTimer"] = [world = context.mWorldView](const AsyncPackageId&, double delay,
const TimerCallback& callback, sol::main_object callbackArg) {
callback.mAsyncId.mContainer->setupSerializableTimer(TimerType::GAME_TIME, world->getGameTime() + delay,
callback.mAsyncId.mScriptId, callback.mName, std::move(callbackArg));
};
api["newUnsavableSimulationTimer"] = [world = context.mWorldView](const AsyncPackageId& asyncId, double delay,
sol::main_protected_function callback) {
asyncId.mContainer->setupUnsavableTimer(
TimerType::SIMULATION_TIME, world->getSimulationTime() + delay, asyncId.mScriptId, std::move(callback));
};
api["newUnsavableGameTimer"] = [world = context.mWorldView](const AsyncPackageId& asyncId, double delay,
sol::main_protected_function callback) {
asyncId.mContainer->setupUnsavableTimer(
TimerType::GAME_TIME, world->getGameTime() + delay, asyncId.mScriptId, std::move(callback));
};
api["callback"] = [](const AsyncPackageId& asyncId, sol::main_protected_function fn) -> LuaUtil::Callback {
return LuaUtil::Callback{ std::move(fn), asyncId.mHiddenData };
};
sol::usertype<LuaUtil::Callback> callbackType = context.mLua->sol().new_usertype<LuaUtil::Callback>("Callback");
callbackType[sol::meta_function::call]
= [](const LuaUtil::Callback& callback, sol::variadic_args va) { return callback.call(sol::as_args(va)); };
auto initializer = [](sol::table hiddenData) {
LuaUtil::ScriptId id = hiddenData[LuaUtil::ScriptsContainer::sScriptIdKey];
return AsyncPackageId{ id.mContainer, id.mIndex, hiddenData };
};
return sol::make_object(context.mLua->sol(), initializer);
}
}

@ -34,15 +34,6 @@ namespace MWLua
void initCellBindingsForLocalScripts(const Context&); void initCellBindingsForLocalScripts(const Context&);
void initCellBindingsForGlobalScripts(const Context&); void initCellBindingsForGlobalScripts(const Context&);
// Implemented in asyncbindings.cpp
struct AsyncPackageId
{
LuaUtil::ScriptsContainer* mContainer;
int mScriptId;
sol::table mHiddenData;
};
sol::function getAsyncPackageInitializer(const Context&);
// Implemented in camerabindings.cpp // Implemented in camerabindings.cpp
sol::table initCameraPackage(const Context&); sol::table initCameraPackage(const Context&);

@ -16,6 +16,7 @@
#include <components/l10n/manager.hpp> #include <components/l10n/manager.hpp>
#include <components/lua/asyncpackage.hpp>
#include <components/lua/utilpackage.hpp> #include <components/lua/utilpackage.hpp>
#include <components/lua_ui/content.hpp> #include <components/lua_ui/content.hpp>
@ -95,7 +96,10 @@ namespace MWLua
LocalScripts::initializeSelfPackage(localContext); LocalScripts::initializeSelfPackage(localContext);
LuaUtil::LuaStorage::initLuaBindings(mLua.sol()); LuaUtil::LuaStorage::initLuaBindings(mLua.sol());
mLua.addCommonPackage("openmw.async", getAsyncPackageInitializer(context)); mLua.addCommonPackage("openmw.async",
LuaUtil::getAsyncPackageInitializer(
mLua.sol(), [this] { return mWorldView.getSimulationTime(); },
[this] { return mWorldView.getGameTime(); }));
mLua.addCommonPackage("openmw.util", LuaUtil::initUtilPackage(mLua.sol())); mLua.addCommonPackage("openmw.util", LuaUtil::initUtilPackage(mLua.sol()));
mLua.addCommonPackage("openmw.core", initCorePackage(context)); mLua.addCommonPackage("openmw.core", initCorePackage(context));
mLua.addCommonPackage("openmw.types", initTypesPackage(context)); mLua.addCommonPackage("openmw.types", initTypesPackage(context));

@ -1,8 +1,8 @@
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <components/lua/asyncpackage.hpp>
#include <components/lua/luastate.hpp> #include <components/lua/luastate.hpp>
#include <components/lua/scriptscontainer.hpp>
#include "../testing_util.hpp" #include "../testing_util.hpp"

@ -3,6 +3,7 @@
#include <components/esm/luascripts.hpp> #include <components/esm/luascripts.hpp>
#include <components/lua/asyncpackage.hpp>
#include <components/lua/luastate.hpp> #include <components/lua/luastate.hpp>
#include <components/lua/scriptscontainer.hpp> #include <components/lua/scriptscontainer.hpp>

@ -34,7 +34,7 @@ endif (GIT_CHECKOUT)
# source files # source files
add_component_dir (lua add_component_dir (lua
luastate scriptscontainer utilpackage serialization configuration l10n storage luastate scriptscontainer asyncpackage utilpackage serialization configuration l10n storage
) )
add_component_dir (l10n add_component_dir (l10n

@ -0,0 +1,71 @@
#include "asyncpackage.hpp"
namespace sol
{
template <>
struct is_automagical<LuaUtil::AsyncPackageId> : std::false_type
{
};
template <>
struct is_automagical<LuaUtil::Callback> : std::false_type
{
};
}
namespace LuaUtil
{
struct TimerCallback
{
AsyncPackageId mAsyncId;
std::string mName;
};
sol::function getAsyncPackageInitializer(
lua_State* L, std::function<double()> simulationTimeFn, std::function<double()> gameTimeFn)
{
sol::state_view lua(L);
using TimerType = ScriptsContainer::TimerType;
sol::usertype<AsyncPackageId> api = lua.new_usertype<AsyncPackageId>("AsyncPackage");
api["registerTimerCallback"]
= [](const AsyncPackageId& asyncId, std::string_view name, sol::main_protected_function callback) {
asyncId.mContainer->registerTimerCallback(asyncId.mScriptId, name, std::move(callback));
return TimerCallback{ asyncId, std::string(name) };
};
api["newSimulationTimer"] = [simulationTimeFn](const AsyncPackageId&, double delay,
const TimerCallback& callback, sol::main_object callbackArg) {
callback.mAsyncId.mContainer->setupSerializableTimer(TimerType::SIMULATION_TIME, simulationTimeFn() + delay,
callback.mAsyncId.mScriptId, callback.mName, std::move(callbackArg));
};
api["newGameTimer"] = [gameTimeFn](const AsyncPackageId&, double delay, const TimerCallback& callback,
sol::main_object callbackArg) {
callback.mAsyncId.mContainer->setupSerializableTimer(TimerType::GAME_TIME, gameTimeFn() + delay,
callback.mAsyncId.mScriptId, callback.mName, std::move(callbackArg));
};
api["newUnsavableSimulationTimer"]
= [simulationTimeFn](const AsyncPackageId& asyncId, double delay, sol::main_protected_function callback) {
asyncId.mContainer->setupUnsavableTimer(
TimerType::SIMULATION_TIME, simulationTimeFn() + delay, asyncId.mScriptId, std::move(callback));
};
api["newUnsavableGameTimer"]
= [gameTimeFn](const AsyncPackageId& asyncId, double delay, sol::main_protected_function callback) {
asyncId.mContainer->setupUnsavableTimer(
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");
callbackType[sol::meta_function::call]
= [](const Callback& callback, sol::variadic_args va) { return callback.call(sol::as_args(va)); };
auto initializer = [](sol::table hiddenData) {
ScriptId id = hiddenData[ScriptsContainer::sScriptIdKey];
return AsyncPackageId{ id.mContainer, id.mIndex, hiddenData };
};
return sol::make_object(lua, initializer);
}
}

@ -0,0 +1,54 @@
#ifndef COMPONENTS_LUA_ASYNCPACKAGE_H
#define COMPONENTS_LUA_ASYNCPACKAGE_H
#include "scriptscontainer.hpp"
namespace LuaUtil
{
struct AsyncPackageId
{
ScriptsContainer* mContainer;
int mScriptId;
sol::table mHiddenData;
};
sol::function getAsyncPackageInitializer(
lua_State* L, std::function<double()> simulationTimeFn, std::function<double()> gameTimeFn);
// Wrapper for a Lua function.
// Holds information about the script the function belongs to.
// Needed to prevent callback calls if the script was removed.
struct Callback
{
sol::main_protected_function mFunc;
sol::table mHiddenData; // same object as Script::mHiddenData in ScriptsContainer
bool isValid() const { return mHiddenData[ScriptsContainer::sScriptIdKey] != sol::nil; }
template <typename... Args>
sol::object call(Args&&... args) const
{
sol::optional<ScriptId> scriptId = mHiddenData[ScriptsContainer::sScriptIdKey];
if (scriptId.has_value())
return LuaUtil::call(scriptId.value(), mFunc, std::forward<Args>(args)...);
else
Log(Debug::Debug) << "Ignored callback to the removed script "
<< mHiddenData.get<std::string>(ScriptsContainer::sScriptDebugNameKey);
return sol::nil;
}
template <typename... Args>
void tryCall(Args&&... args) const
{
try
{
this->call(std::forward<Args>(args)...);
}
catch (std::exception& e)
{
Log(Debug::Error) << "Error in callback: " << e.what();
}
}
};
}
#endif // COMPONENTS_LUA_ASYNCPACKAGE_H

@ -269,43 +269,6 @@ namespace LuaUtil
static int64_t sInstanceCount; // debug information, shown in Lua profiler static int64_t sInstanceCount; // debug information, shown in Lua profiler
}; };
// Wrapper for a Lua function.
// Holds information about the script the function belongs to.
// Needed to prevent callback calls if the script was removed.
struct Callback
{
sol::main_protected_function mFunc;
sol::table mHiddenData; // same object as Script::mHiddenData in ScriptsContainer
bool isValid() const { return mHiddenData[ScriptsContainer::sScriptIdKey] != sol::nil; }
template <typename... Args>
sol::object call(Args&&... args) const
{
sol::optional<ScriptId> scriptId = mHiddenData[ScriptsContainer::sScriptIdKey];
if (scriptId.has_value())
return LuaUtil::call(scriptId.value(), mFunc, std::forward<Args>(args)...);
else
Log(Debug::Debug) << "Ignored callback to the removed script "
<< mHiddenData.get<std::string>(ScriptsContainer::sScriptDebugNameKey);
return sol::nil;
}
template <typename... Args>
void tryCall(Args&&... args) const
{
try
{
this->call(std::forward<Args>(args)...);
}
catch (std::exception& e)
{
Log(Debug::Error) << "Error in callback: " << e.what();
}
}
};
} }
#endif // COMPONENTS_LUA_SCRIPTSCONTAINER_H #endif // COMPONENTS_LUA_SCRIPTSCONTAINER_H

@ -4,7 +4,7 @@
#include <map> #include <map>
#include <sol/sol.hpp> #include <sol/sol.hpp>
#include "scriptscontainer.hpp" #include "asyncpackage.hpp"
#include "serialization.hpp" #include "serialization.hpp"
namespace LuaUtil namespace LuaUtil

@ -7,7 +7,7 @@
#include <MyGUI_Widget.h> #include <MyGUI_Widget.h>
#include <sol/sol.hpp> #include <sol/sol.hpp>
#include <components/lua/scriptscontainer.hpp> #include <components/lua/asyncpackage.hpp>
#include "properties.hpp" #include "properties.hpp"

Loading…
Cancel
Save