mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-05-13 14:06:42 +03:00
Remove LuaManager::Action
This commit is contained in:
parent
4562b8c06b
commit
003f611bdb
6 changed files with 132 additions and 272 deletions
|
@ -206,12 +206,12 @@ namespace MWLua
|
||||||
windowManager->printToConsole(msg, "#" + color.toHex());
|
windowManager->printToConsole(msg, "#" + color.toHex());
|
||||||
mInGameConsoleMessages.clear();
|
mInGameConsoleMessages.clear();
|
||||||
|
|
||||||
for (std::unique_ptr<Action>& action : mActionQueue)
|
for (DelayedAction& action : mActionQueue)
|
||||||
action->safeApply();
|
action.apply();
|
||||||
mActionQueue.clear();
|
mActionQueue.clear();
|
||||||
|
|
||||||
if (mTeleportPlayerAction)
|
if (mTeleportPlayerAction)
|
||||||
mTeleportPlayerAction->safeApply();
|
mTeleportPlayerAction->apply();
|
||||||
mTeleportPlayerAction.reset();
|
mTeleportPlayerAction.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,22 +465,24 @@ namespace MWLua
|
||||||
"No Lua handlers for console\n", MWBase::WindowManager::sConsoleColor_Error);
|
"No Lua handlers for console\n", MWBase::WindowManager::sConsoleColor_Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
LuaManager::Action::Action(LuaUtil::LuaState* state)
|
LuaManager::DelayedAction::DelayedAction(LuaUtil::LuaState* state, std::function<void()> fn, std::string_view name)
|
||||||
|
: mFn(std::move(fn))
|
||||||
|
, mName(name)
|
||||||
{
|
{
|
||||||
static const bool luaDebug = Settings::Manager::getBool("lua debug", "Lua");
|
static const bool luaDebug = Settings::Manager::getBool("lua debug", "Lua");
|
||||||
if (luaDebug)
|
if (luaDebug)
|
||||||
mCallerTraceback = state->debugTraceback();
|
mCallerTraceback = state->debugTraceback();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaManager::Action::safeApply() const
|
void LuaManager::DelayedAction::apply() const
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
apply();
|
mFn();
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
Log(Debug::Error) << "Error in " << this->toString() << ": " << e.what();
|
Log(Debug::Error) << "Error in DelayedAction " << mName << ": " << e.what();
|
||||||
|
|
||||||
if (mCallerTraceback.empty())
|
if (mCallerTraceback.empty())
|
||||||
Log(Debug::Error) << "Set 'lua_debug=true' in settings.cfg to enable action tracebacks";
|
Log(Debug::Error) << "Set 'lua_debug=true' in settings.cfg to enable action tracebacks";
|
||||||
|
@ -489,35 +491,14 @@ namespace MWLua
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
class FunctionAction final : public LuaManager::Action
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FunctionAction(LuaUtil::LuaState* state, std::function<void()> fn, std::string_view name)
|
|
||||||
: Action(state)
|
|
||||||
, mFn(std::move(fn))
|
|
||||||
, mName(name)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply() const override { mFn(); }
|
|
||||||
std::string toString() const override { return "FunctionAction " + mName; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::function<void()> mFn;
|
|
||||||
std::string mName;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void LuaManager::addAction(std::function<void()> action, std::string_view name)
|
void LuaManager::addAction(std::function<void()> action, std::string_view name)
|
||||||
{
|
{
|
||||||
mActionQueue.push_back(std::make_unique<FunctionAction>(&mLua, std::move(action), name));
|
mActionQueue.emplace_back(&mLua, std::move(action), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaManager::addTeleportPlayerAction(std::function<void()> action)
|
void LuaManager::addTeleportPlayerAction(std::function<void()> action)
|
||||||
{
|
{
|
||||||
mTeleportPlayerAction = std::make_unique<FunctionAction>(&mLua, std::move(action), "TeleportPlayer");
|
mTeleportPlayerAction = DelayedAction(&mLua, std::move(action), "TeleportPlayer");
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaManager::reportStats(unsigned int frameNumber, osg::Stats& stats) const
|
void LuaManager::reportStats(unsigned int frameNumber, osg::Stats& stats) const
|
||||||
|
|
|
@ -86,24 +86,8 @@ namespace MWLua
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some changes to the game world can not be done from the scripting thread (because it runs in parallel with
|
// Some changes to the game world can not be done from the scripting thread (because it runs in parallel with
|
||||||
// OSG Cull), so we need to queue it and apply from the main thread. All such changes should be implemented as
|
// OSG Cull), so we need to queue it and apply from the main thread.
|
||||||
// classes inherited from MWLua::Action.
|
|
||||||
class Action
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Action(LuaUtil::LuaState* state);
|
|
||||||
virtual ~Action() {}
|
|
||||||
|
|
||||||
void safeApply() const;
|
|
||||||
virtual void apply() const = 0;
|
|
||||||
virtual std::string toString() const = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string mCallerTraceback;
|
|
||||||
};
|
|
||||||
|
|
||||||
void addAction(std::function<void()> action, std::string_view name = "");
|
void addAction(std::function<void()> action, std::string_view name = "");
|
||||||
void addAction(std::unique_ptr<Action>&& action) { mActionQueue.push_back(std::move(action)); }
|
|
||||||
void addTeleportPlayerAction(std::function<void()> action);
|
void addTeleportPlayerAction(std::function<void()> action);
|
||||||
|
|
||||||
// Saving
|
// Saving
|
||||||
|
@ -183,8 +167,19 @@ namespace MWLua
|
||||||
std::vector<CallbackWithData> mQueuedCallbacks;
|
std::vector<CallbackWithData> mQueuedCallbacks;
|
||||||
|
|
||||||
// Queued actions that should be done in main thread. Processed by applyQueuedChanges().
|
// Queued actions that should be done in main thread. Processed by applyQueuedChanges().
|
||||||
std::vector<std::unique_ptr<Action>> mActionQueue;
|
class DelayedAction
|
||||||
std::unique_ptr<Action> mTeleportPlayerAction;
|
{
|
||||||
|
public:
|
||||||
|
DelayedAction(LuaUtil::LuaState* state, std::function<void()> fn, std::string_view name);
|
||||||
|
void apply() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string mCallerTraceback;
|
||||||
|
std::function<void()> mFn;
|
||||||
|
std::string mName;
|
||||||
|
};
|
||||||
|
std::vector<DelayedAction> mActionQueue;
|
||||||
|
std::optional<DelayedAction> mTeleportPlayerAction;
|
||||||
std::vector<std::string> mUIMessages;
|
std::vector<std::string> mUIMessages;
|
||||||
std::vector<std::pair<std::string, Misc::Color>> mInGameConsoleMessages;
|
std::vector<std::pair<std::string, Misc::Color>> mInGameConsoleMessages;
|
||||||
|
|
||||||
|
|
|
@ -5,39 +5,6 @@
|
||||||
|
|
||||||
#include "luamanagerimp.hpp"
|
#include "luamanagerimp.hpp"
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
template <class T>
|
|
||||||
class SetUniformShaderAction final : public MWLua::LuaManager::Action
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SetUniformShaderAction(
|
|
||||||
LuaUtil::LuaState* state, std::shared_ptr<fx::Technique> shader, const std::string& name, const T& value)
|
|
||||||
: MWLua::LuaManager::Action(state)
|
|
||||||
, mShader(std::move(shader))
|
|
||||||
, mName(name)
|
|
||||||
, mValue(value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply() const override
|
|
||||||
{
|
|
||||||
MWBase::Environment::get().getWorld()->getPostProcessor()->setUniform(mShader, mName, mValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string toString() const override
|
|
||||||
{
|
|
||||||
return std::string("SetUniformShaderAction shader=") + (mShader ? mShader->getName() : "nil")
|
|
||||||
+ std::string("uniform=") + (mShader ? mName : "nil");
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::shared_ptr<fx::Technique> mShader;
|
|
||||||
std::string mName;
|
|
||||||
T mValue;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
struct Shader;
|
struct Shader;
|
||||||
|
@ -84,7 +51,10 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
return [context](const Shader& shader, const std::string& name, const T& value) {
|
return [context](const Shader& shader, const std::string& name, const T& value) {
|
||||||
context.mLuaManager->addAction(
|
context.mLuaManager->addAction(
|
||||||
std::make_unique<SetUniformShaderAction<T>>(context.mLua, shader.mShader, name, value));
|
[&] {
|
||||||
|
MWBase::Environment::get().getWorld()->getPostProcessor()->setUniform(shader.mShader, name, value);
|
||||||
|
},
|
||||||
|
"SetUniformShaderAction");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +84,10 @@ namespace MWLua
|
||||||
}
|
}
|
||||||
|
|
||||||
context.mLuaManager->addAction(
|
context.mLuaManager->addAction(
|
||||||
std::make_unique<SetUniformShaderAction<std::vector<T>>>(context.mLua, shader.mShader, name, values));
|
[&] {
|
||||||
|
MWBase::Environment::get().getWorld()->getPostProcessor()->setUniform(shader.mShader, name, values);
|
||||||
|
},
|
||||||
|
"SetUniformShaderAction");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,29 +55,17 @@ namespace
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
namespace
|
static void addStatUpdateAction(MWLua::LuaManager* manager, const SelfObject& obj)
|
||||||
{
|
{
|
||||||
class StatUpdateAction final : public LuaManager::Action
|
if (!obj.mStatsCache.empty())
|
||||||
{
|
return; // was already added before
|
||||||
ObjectId mId;
|
manager->addAction(
|
||||||
|
[obj = Object(obj)] {
|
||||||
public:
|
|
||||||
StatUpdateAction(LuaUtil::LuaState* state, ObjectId id)
|
|
||||||
: Action(state)
|
|
||||||
, mId(id)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply() const override
|
|
||||||
{
|
|
||||||
LObject obj(mId);
|
|
||||||
LocalScripts* scripts = obj.ptr().getRefData().getLuaScripts();
|
LocalScripts* scripts = obj.ptr().getRefData().getLuaScripts();
|
||||||
if (scripts)
|
if (scripts)
|
||||||
scripts->applyStatsCache();
|
scripts->applyStatsCache();
|
||||||
}
|
},
|
||||||
|
"StatUpdateAction");
|
||||||
std::string toString() const override { return "StatUpdateAction"; }
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class LevelStat
|
class LevelStat
|
||||||
|
@ -99,8 +87,7 @@ namespace MWLua
|
||||||
void setCurrent(const Context& context, const sol::object& value) const
|
void setCurrent(const Context& context, const sol::object& value) const
|
||||||
{
|
{
|
||||||
SelfObject* obj = mObject.asSelfObject();
|
SelfObject* obj = mObject.asSelfObject();
|
||||||
if (obj->mStatsCache.empty())
|
addStatUpdateAction(context.mLuaManager, *obj);
|
||||||
context.mLuaManager->addAction(std::make_unique<StatUpdateAction>(context.mLua, obj->id()));
|
|
||||||
obj->mStatsCache[SelfObject::CachedStat{ &LevelStat::setValue, 0, "current" }] = value;
|
obj->mStatsCache[SelfObject::CachedStat{ &LevelStat::setValue, 0, "current" }] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,8 +145,7 @@ namespace MWLua
|
||||||
void cache(const Context& context, std::string_view prop, const sol::object& value) const
|
void cache(const Context& context, std::string_view prop, const sol::object& value) const
|
||||||
{
|
{
|
||||||
SelfObject* obj = mObject.asSelfObject();
|
SelfObject* obj = mObject.asSelfObject();
|
||||||
if (obj->mStatsCache.empty())
|
addStatUpdateAction(context.mLuaManager, *obj);
|
||||||
context.mLuaManager->addAction(std::make_unique<StatUpdateAction>(context.mLua, obj->id()));
|
|
||||||
obj->mStatsCache[SelfObject::CachedStat{ &DynamicStat::setValue, mIndex, prop }] = value;
|
obj->mStatsCache[SelfObject::CachedStat{ &DynamicStat::setValue, mIndex, prop }] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,8 +203,7 @@ namespace MWLua
|
||||||
void cache(const Context& context, std::string_view prop, const sol::object& value) const
|
void cache(const Context& context, std::string_view prop, const sol::object& value) const
|
||||||
{
|
{
|
||||||
SelfObject* obj = mObject.asSelfObject();
|
SelfObject* obj = mObject.asSelfObject();
|
||||||
if (obj->mStatsCache.empty())
|
addStatUpdateAction(context.mLuaManager, *obj);
|
||||||
context.mLuaManager->addAction(std::make_unique<StatUpdateAction>(context.mLua, obj->id()));
|
|
||||||
obj->mStatsCache[SelfObject::CachedStat{ &AttributeStat::setValue, mIndex, prop }] = value;
|
obj->mStatsCache[SelfObject::CachedStat{ &AttributeStat::setValue, mIndex, prop }] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,8 +287,7 @@ namespace MWLua
|
||||||
void cache(const Context& context, std::string_view prop, const sol::object& value) const
|
void cache(const Context& context, std::string_view prop, const sol::object& value) const
|
||||||
{
|
{
|
||||||
SelfObject* obj = mObject.asSelfObject();
|
SelfObject* obj = mObject.asSelfObject();
|
||||||
if (obj->mStatsCache.empty())
|
addStatUpdateAction(context.mLuaManager, *obj);
|
||||||
context.mLuaManager->addAction(std::make_unique<StatUpdateAction>(context.mLua, obj->id()));
|
|
||||||
obj->mStatsCache[SelfObject::CachedStat{ &SkillStat::setValue, mIndex, prop }] = value;
|
obj->mStatsCache[SelfObject::CachedStat{ &SkillStat::setValue, mIndex, prop }] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,30 +18,17 @@
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
namespace
|
using EquipmentItem = std::variant<std::string, ObjectId>;
|
||||||
{
|
using Equipment = std::map<int, EquipmentItem>;
|
||||||
class SetEquipmentAction final : public LuaManager::Action
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using Item = std::variant<std::string, ObjectId>; // recordId or ObjectId
|
|
||||||
using Equipment = std::map<int, Item>; // slot to item
|
|
||||||
|
|
||||||
SetEquipmentAction(LuaUtil::LuaState* state, ObjectId actor, Equipment equipment)
|
static void setEquipment(const MWWorld::Ptr& actor, const Equipment& equipment)
|
||||||
: Action(state)
|
|
||||||
, mActor(actor)
|
|
||||||
, mEquipment(std::move(equipment))
|
|
||||||
{
|
{
|
||||||
}
|
|
||||||
|
|
||||||
void apply() const override
|
|
||||||
{
|
|
||||||
MWWorld::Ptr actor = MWBase::Environment::get().getWorldModel()->getPtr(mActor);
|
|
||||||
MWWorld::InventoryStore& store = actor.getClass().getInventoryStore(actor);
|
MWWorld::InventoryStore& store = actor.getClass().getInventoryStore(actor);
|
||||||
std::array<bool, MWWorld::InventoryStore::Slots> usedSlots;
|
std::array<bool, MWWorld::InventoryStore::Slots> usedSlots;
|
||||||
std::fill(usedSlots.begin(), usedSlots.end(), false);
|
std::fill(usedSlots.begin(), usedSlots.end(), false);
|
||||||
|
|
||||||
static constexpr int anySlot = -1;
|
static constexpr int anySlot = -1;
|
||||||
auto tryEquipToSlot = [&store, &usedSlots](int slot, const Item& item) -> bool {
|
auto tryEquipToSlot = [&store, &usedSlots](int slot, const EquipmentItem& item) -> bool {
|
||||||
auto old_it = slot != anySlot ? store.getSlot(slot) : store.end();
|
auto old_it = slot != anySlot ? store.getSlot(slot) : store.end();
|
||||||
MWWorld::Ptr itemPtr;
|
MWWorld::Ptr itemPtr;
|
||||||
if (std::holds_alternative<ObjectId>(item))
|
if (std::holds_alternative<ObjectId>(item))
|
||||||
|
@ -52,8 +39,7 @@ namespace MWLua
|
||||||
if (itemPtr.isEmpty() || itemPtr.getRefData().getCount() == 0
|
if (itemPtr.isEmpty() || itemPtr.getRefData().getCount() == 0
|
||||||
|| itemPtr.getContainerStore() != static_cast<const MWWorld::ContainerStore*>(&store))
|
|| itemPtr.getContainerStore() != static_cast<const MWWorld::ContainerStore*>(&store))
|
||||||
{
|
{
|
||||||
Log(Debug::Warning)
|
Log(Debug::Warning) << "Object" << std::get<ObjectId>(item).toString() << " is not in inventory";
|
||||||
<< "Object" << std::get<ObjectId>(item).toString() << " is not in inventory";
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,8 +61,8 @@ namespace MWLua
|
||||||
= std::find(allowedSlots.begin(), allowedSlots.end(), slot) != allowedSlots.end();
|
= std::find(allowedSlots.begin(), allowedSlots.end(), slot) != allowedSlots.end();
|
||||||
if (!requestedSlotIsAllowed)
|
if (!requestedSlotIsAllowed)
|
||||||
{
|
{
|
||||||
auto firstAllowed = std::find_if(
|
auto firstAllowed
|
||||||
allowedSlots.begin(), allowedSlots.end(), [&](int s) { return !usedSlots[s]; });
|
= std::find_if(allowedSlots.begin(), allowedSlots.end(), [&](int s) { return !usedSlots[s]; });
|
||||||
if (firstAllowed == allowedSlots.end())
|
if (firstAllowed == allowedSlots.end())
|
||||||
{
|
{
|
||||||
Log(Debug::Warning) << "No suitable slot for " << itemPtr.toString();
|
Log(Debug::Warning) << "No suitable slot for " << itemPtr.toString();
|
||||||
|
@ -91,15 +77,14 @@ namespace MWLua
|
||||||
throw std::logic_error("Item not found in container");
|
throw std::logic_error("Item not found in container");
|
||||||
|
|
||||||
store.equip(slot, it);
|
store.equip(slot, it);
|
||||||
return requestedSlotIsAllowed; // return true if equipped to requested slot and false if slot was
|
return requestedSlotIsAllowed; // return true if equipped to requested slot and false if slot was changed
|
||||||
// changed
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
||||||
{
|
{
|
||||||
auto old_it = store.getSlot(slot);
|
auto old_it = store.getSlot(slot);
|
||||||
auto new_it = mEquipment.find(slot);
|
auto new_it = equipment.find(slot);
|
||||||
if (new_it == mEquipment.end())
|
if (new_it == equipment.end())
|
||||||
{
|
{
|
||||||
if (old_it != store.end())
|
if (old_it != store.end())
|
||||||
store.unequipSlot(slot);
|
store.unequipSlot(slot);
|
||||||
|
@ -108,19 +93,11 @@ namespace MWLua
|
||||||
if (tryEquipToSlot(slot, new_it->second))
|
if (tryEquipToSlot(slot, new_it->second))
|
||||||
usedSlots[slot] = true;
|
usedSlots[slot] = true;
|
||||||
}
|
}
|
||||||
for (const auto& [slot, item] : mEquipment)
|
for (const auto& [slot, item] : equipment)
|
||||||
if (slot >= MWWorld::InventoryStore::Slots)
|
if (slot >= MWWorld::InventoryStore::Slots)
|
||||||
tryEquipToSlot(anySlot, item);
|
tryEquipToSlot(anySlot, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string toString() const override { return "SetEquipmentAction"; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
ObjectId mActor;
|
|
||||||
Equipment mEquipment;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void addActorBindings(sol::table actor, const Context& context)
|
void addActorBindings(sol::table actor, const Context& context)
|
||||||
{
|
{
|
||||||
actor["STANCE"]
|
actor["STANCE"]
|
||||||
|
@ -263,13 +240,14 @@ namespace MWLua
|
||||||
return store.isEquipped(item.ptr());
|
return store.isEquipped(item.ptr());
|
||||||
};
|
};
|
||||||
actor["setEquipment"] = [context](const SelfObject& obj, const sol::table& equipment) {
|
actor["setEquipment"] = [context](const SelfObject& obj, const sol::table& equipment) {
|
||||||
if (!obj.ptr().getClass().hasInventoryStore(obj.ptr()))
|
const MWWorld::Ptr& ptr = obj.ptr();
|
||||||
|
if (!ptr.getClass().hasInventoryStore(ptr))
|
||||||
{
|
{
|
||||||
if (!equipment.empty())
|
if (!equipment.empty())
|
||||||
throw std::runtime_error(obj.toString() + " has no equipment slots");
|
throw std::runtime_error(obj.toString() + " has no equipment slots");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SetEquipmentAction::Equipment eqp;
|
Equipment eqp;
|
||||||
for (auto& [key, value] : equipment)
|
for (auto& [key, value] : equipment)
|
||||||
{
|
{
|
||||||
int slot = key.as<int>();
|
int slot = key.as<int>();
|
||||||
|
@ -279,7 +257,7 @@ namespace MWLua
|
||||||
eqp[slot] = value.as<std::string>();
|
eqp[slot] = value.as<std::string>();
|
||||||
}
|
}
|
||||||
context.mLuaManager->addAction(
|
context.mLuaManager->addAction(
|
||||||
std::make_unique<SetEquipmentAction>(context.mLua, obj.id(), std::move(eqp)));
|
[obj = Object(ptr), eqp = std::move(eqp)] { setEquipment(obj.ptr(), eqp); }, "SetEquipmentAction");
|
||||||
};
|
};
|
||||||
actor["getPathfindingAgentBounds"] = [](sol::this_state lua, const LObject& o) {
|
actor["getPathfindingAgentBounds"] = [](sol::this_state lua, const LObject& o) {
|
||||||
const DetourNavigator::AgentBounds agentBounds
|
const DetourNavigator::AgentBounds agentBounds
|
||||||
|
|
|
@ -20,72 +20,21 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
class UiAction final : public LuaManager::Action
|
template <typename Fn>
|
||||||
{
|
void wrapAction(const std::shared_ptr<LuaUi::Element>& element, Fn&& fn)
|
||||||
public:
|
|
||||||
enum Type
|
|
||||||
{
|
|
||||||
CREATE = 0,
|
|
||||||
UPDATE,
|
|
||||||
DESTROY,
|
|
||||||
};
|
|
||||||
|
|
||||||
UiAction(Type type, std::shared_ptr<LuaUi::Element> element, LuaUtil::LuaState* state)
|
|
||||||
: Action(state)
|
|
||||||
, mType{ type }
|
|
||||||
, mElement{ std::move(element) }
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply() const override
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
switch (mType)
|
fn();
|
||||||
{
|
|
||||||
case CREATE:
|
|
||||||
mElement->create();
|
|
||||||
break;
|
|
||||||
case UPDATE:
|
|
||||||
mElement->update();
|
|
||||||
break;
|
|
||||||
case DESTROY:
|
|
||||||
mElement->destroy();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
catch (...)
|
||||||
catch (std::exception&)
|
|
||||||
{
|
{
|
||||||
// prevent any actions on a potentially corrupted widget
|
// prevent any actions on a potentially corrupted widget
|
||||||
mElement->mRoot = nullptr;
|
element->mRoot = nullptr;
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string toString() const override
|
|
||||||
{
|
|
||||||
std::string result;
|
|
||||||
switch (mType)
|
|
||||||
{
|
|
||||||
case CREATE:
|
|
||||||
result += "Create";
|
|
||||||
break;
|
|
||||||
case UPDATE:
|
|
||||||
result += "Update";
|
|
||||||
break;
|
|
||||||
case DESTROY:
|
|
||||||
result += "Destroy";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
result += " UI";
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Type mType;
|
|
||||||
std::shared_ptr<LuaUi::Element> mElement;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Lua arrays index from 1
|
// Lua arrays index from 1
|
||||||
inline size_t fromLuaIndex(size_t i)
|
inline size_t fromLuaIndex(size_t i)
|
||||||
{
|
{
|
||||||
|
@ -102,17 +51,17 @@ namespace MWLua
|
||||||
auto element = context.mLua->sol().new_usertype<LuaUi::Element>("Element");
|
auto element = context.mLua->sol().new_usertype<LuaUi::Element>("Element");
|
||||||
element["layout"] = sol::property([](LuaUi::Element& element) { return element.mLayout; },
|
element["layout"] = sol::property([](LuaUi::Element& element) { return element.mLayout; },
|
||||||
[](LuaUi::Element& element, const sol::table& layout) { element.mLayout = layout; });
|
[](LuaUi::Element& element, const sol::table& layout) { element.mLayout = layout; });
|
||||||
element["update"] = [context](const std::shared_ptr<LuaUi::Element>& element) {
|
element["update"] = [luaManager = context.mLuaManager](const std::shared_ptr<LuaUi::Element>& element) {
|
||||||
if (element->mDestroy || element->mUpdate)
|
if (element->mDestroy || element->mUpdate)
|
||||||
return;
|
return;
|
||||||
element->mUpdate = true;
|
element->mUpdate = true;
|
||||||
context.mLuaManager->addAction(std::make_unique<UiAction>(UiAction::UPDATE, element, context.mLua));
|
luaManager->addAction([element] { wrapAction(element, [&] { element->update(); }); }, "Update UI");
|
||||||
};
|
};
|
||||||
element["destroy"] = [context](const std::shared_ptr<LuaUi::Element>& element) {
|
element["destroy"] = [luaManager = context.mLuaManager](const std::shared_ptr<LuaUi::Element>& element) {
|
||||||
if (element->mDestroy)
|
if (element->mDestroy)
|
||||||
return;
|
return;
|
||||||
element->mDestroy = true;
|
element->mDestroy = true;
|
||||||
context.mLuaManager->addAction(std::make_unique<UiAction>(UiAction::DESTROY, element, context.mLua));
|
luaManager->addAction([element] { wrapAction(element, [&] { element->destroy(); }); }, "Destroy UI");
|
||||||
};
|
};
|
||||||
|
|
||||||
sol::table api = context.mLua->newTable();
|
sol::table api = context.mLua->newTable();
|
||||||
|
@ -144,9 +93,9 @@ namespace MWLua
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
api["content"] = LuaUi::loadContentConstructor(context.mLua);
|
api["content"] = LuaUi::loadContentConstructor(context.mLua);
|
||||||
api["create"] = [context](const sol::table& layout) {
|
api["create"] = [luaManager = context.mLuaManager](const sol::table& layout) {
|
||||||
auto element = LuaUi::Element::make(layout);
|
auto element = LuaUi::Element::make(layout);
|
||||||
context.mLuaManager->addAction(std::make_unique<UiAction>(UiAction::CREATE, element, context.mLua));
|
luaManager->addAction([element] { wrapAction(element, [&] { element->create(); }); }, "Create UI");
|
||||||
return element;
|
return element;
|
||||||
};
|
};
|
||||||
api["updateAll"] = [context]() {
|
api["updateAll"] = [context]() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue