mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-21 05:39:42 +00: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());
|
||||
mInGameConsoleMessages.clear();
|
||||
|
||||
for (std::unique_ptr<Action>& action : mActionQueue)
|
||||
action->safeApply();
|
||||
for (DelayedAction& action : mActionQueue)
|
||||
action.apply();
|
||||
mActionQueue.clear();
|
||||
|
||||
if (mTeleportPlayerAction)
|
||||
mTeleportPlayerAction->safeApply();
|
||||
mTeleportPlayerAction->apply();
|
||||
mTeleportPlayerAction.reset();
|
||||
}
|
||||
|
||||
|
@ -465,22 +465,24 @@ namespace MWLua
|
|||
"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");
|
||||
if (luaDebug)
|
||||
mCallerTraceback = state->debugTraceback();
|
||||
}
|
||||
|
||||
void LuaManager::Action::safeApply() const
|
||||
void LuaManager::DelayedAction::apply() const
|
||||
{
|
||||
try
|
||||
{
|
||||
apply();
|
||||
mFn();
|
||||
}
|
||||
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())
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
|
|
|
@ -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
|
||||
// OSG Cull), so we need to queue it and apply from the main thread. All such changes should be implemented as
|
||||
// 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;
|
||||
};
|
||||
|
||||
// OSG Cull), so we need to queue it and apply from the main thread.
|
||||
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);
|
||||
|
||||
// Saving
|
||||
|
@ -183,8 +167,19 @@ namespace MWLua
|
|||
std::vector<CallbackWithData> mQueuedCallbacks;
|
||||
|
||||
// Queued actions that should be done in main thread. Processed by applyQueuedChanges().
|
||||
std::vector<std::unique_ptr<Action>> mActionQueue;
|
||||
std::unique_ptr<Action> mTeleportPlayerAction;
|
||||
class DelayedAction
|
||||
{
|
||||
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::pair<std::string, Misc::Color>> mInGameConsoleMessages;
|
||||
|
||||
|
|
|
@ -5,39 +5,6 @@
|
|||
|
||||
#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
|
||||
{
|
||||
struct Shader;
|
||||
|
@ -84,7 +51,10 @@ namespace MWLua
|
|||
{
|
||||
return [context](const Shader& shader, const std::string& name, const T& value) {
|
||||
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(
|
||||
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
|
||||
static void addStatUpdateAction(MWLua::LuaManager* manager, const SelfObject& obj)
|
||||
{
|
||||
class StatUpdateAction final : public LuaManager::Action
|
||||
{
|
||||
ObjectId mId;
|
||||
|
||||
public:
|
||||
StatUpdateAction(LuaUtil::LuaState* state, ObjectId id)
|
||||
: Action(state)
|
||||
, mId(id)
|
||||
{
|
||||
}
|
||||
|
||||
void apply() const override
|
||||
{
|
||||
LObject obj(mId);
|
||||
if (!obj.mStatsCache.empty())
|
||||
return; // was already added before
|
||||
manager->addAction(
|
||||
[obj = Object(obj)] {
|
||||
LocalScripts* scripts = obj.ptr().getRefData().getLuaScripts();
|
||||
if (scripts)
|
||||
scripts->applyStatsCache();
|
||||
}
|
||||
|
||||
std::string toString() const override { return "StatUpdateAction"; }
|
||||
};
|
||||
},
|
||||
"StatUpdateAction");
|
||||
}
|
||||
|
||||
class LevelStat
|
||||
|
@ -99,8 +87,7 @@ namespace MWLua
|
|||
void setCurrent(const Context& context, const sol::object& value) const
|
||||
{
|
||||
SelfObject* obj = mObject.asSelfObject();
|
||||
if (obj->mStatsCache.empty())
|
||||
context.mLuaManager->addAction(std::make_unique<StatUpdateAction>(context.mLua, obj->id()));
|
||||
addStatUpdateAction(context.mLuaManager, *obj);
|
||||
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
|
||||
{
|
||||
SelfObject* obj = mObject.asSelfObject();
|
||||
if (obj->mStatsCache.empty())
|
||||
context.mLuaManager->addAction(std::make_unique<StatUpdateAction>(context.mLua, obj->id()));
|
||||
addStatUpdateAction(context.mLuaManager, *obj);
|
||||
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
|
||||
{
|
||||
SelfObject* obj = mObject.asSelfObject();
|
||||
if (obj->mStatsCache.empty())
|
||||
context.mLuaManager->addAction(std::make_unique<StatUpdateAction>(context.mLua, obj->id()));
|
||||
addStatUpdateAction(context.mLuaManager, *obj);
|
||||
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
|
||||
{
|
||||
SelfObject* obj = mObject.asSelfObject();
|
||||
if (obj->mStatsCache.empty())
|
||||
context.mLuaManager->addAction(std::make_unique<StatUpdateAction>(context.mLua, obj->id()));
|
||||
addStatUpdateAction(context.mLuaManager, *obj);
|
||||
obj->mStatsCache[SelfObject::CachedStat{ &SkillStat::setValue, mIndex, prop }] = value;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,107 +18,84 @@
|
|||
|
||||
namespace MWLua
|
||||
{
|
||||
namespace
|
||||
using EquipmentItem = std::variant<std::string, ObjectId>;
|
||||
using Equipment = std::map<int, EquipmentItem>;
|
||||
|
||||
static void setEquipment(const MWWorld::Ptr& actor, const Equipment& equipment)
|
||||
{
|
||||
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
|
||||
MWWorld::InventoryStore& store = actor.getClass().getInventoryStore(actor);
|
||||
std::array<bool, MWWorld::InventoryStore::Slots> usedSlots;
|
||||
std::fill(usedSlots.begin(), usedSlots.end(), false);
|
||||
|
||||
SetEquipmentAction(LuaUtil::LuaState* state, ObjectId actor, Equipment equipment)
|
||||
: Action(state)
|
||||
, mActor(actor)
|
||||
, mEquipment(std::move(equipment))
|
||||
static constexpr int anySlot = -1;
|
||||
auto tryEquipToSlot = [&store, &usedSlots](int slot, const EquipmentItem& item) -> bool {
|
||||
auto old_it = slot != anySlot ? store.getSlot(slot) : store.end();
|
||||
MWWorld::Ptr itemPtr;
|
||||
if (std::holds_alternative<ObjectId>(item))
|
||||
{
|
||||
}
|
||||
|
||||
void apply() const override
|
||||
{
|
||||
MWWorld::Ptr actor = MWBase::Environment::get().getWorldModel()->getPtr(mActor);
|
||||
MWWorld::InventoryStore& store = actor.getClass().getInventoryStore(actor);
|
||||
std::array<bool, MWWorld::InventoryStore::Slots> usedSlots;
|
||||
std::fill(usedSlots.begin(), usedSlots.end(), false);
|
||||
|
||||
static constexpr int anySlot = -1;
|
||||
auto tryEquipToSlot = [&store, &usedSlots](int slot, const Item& item) -> bool {
|
||||
auto old_it = slot != anySlot ? store.getSlot(slot) : store.end();
|
||||
MWWorld::Ptr itemPtr;
|
||||
if (std::holds_alternative<ObjectId>(item))
|
||||
{
|
||||
itemPtr = MWBase::Environment::get().getWorldModel()->getPtr(std::get<ObjectId>(item));
|
||||
if (old_it != store.end() && *old_it == itemPtr)
|
||||
return true; // already equipped
|
||||
if (itemPtr.isEmpty() || itemPtr.getRefData().getCount() == 0
|
||||
|| itemPtr.getContainerStore() != static_cast<const MWWorld::ContainerStore*>(&store))
|
||||
{
|
||||
Log(Debug::Warning)
|
||||
<< "Object" << std::get<ObjectId>(item).toString() << " is not in inventory";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const ESM::RefId& recordId = ESM::RefId::stringRefId(std::get<std::string>(item));
|
||||
if (old_it != store.end() && old_it->getCellRef().getRefId() == recordId)
|
||||
return true; // already equipped
|
||||
itemPtr = store.search(recordId);
|
||||
if (itemPtr.isEmpty() || itemPtr.getRefData().getCount() == 0)
|
||||
{
|
||||
Log(Debug::Warning) << "There is no object with recordId='" << recordId << "' in inventory";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
auto [allowedSlots, _] = itemPtr.getClass().getEquipmentSlots(itemPtr);
|
||||
bool requestedSlotIsAllowed
|
||||
= std::find(allowedSlots.begin(), allowedSlots.end(), slot) != allowedSlots.end();
|
||||
if (!requestedSlotIsAllowed)
|
||||
{
|
||||
auto firstAllowed = std::find_if(
|
||||
allowedSlots.begin(), allowedSlots.end(), [&](int s) { return !usedSlots[s]; });
|
||||
if (firstAllowed == allowedSlots.end())
|
||||
{
|
||||
Log(Debug::Warning) << "No suitable slot for " << itemPtr.toString();
|
||||
return false;
|
||||
}
|
||||
slot = *firstAllowed;
|
||||
}
|
||||
|
||||
// TODO: Refactor InventoryStore to accept Ptr and get rid of this linear search.
|
||||
MWWorld::ContainerStoreIterator it = std::find(store.begin(), store.end(), itemPtr);
|
||||
if (it == store.end()) // should never happen
|
||||
throw std::logic_error("Item not found in container");
|
||||
|
||||
store.equip(slot, it);
|
||||
return requestedSlotIsAllowed; // return true if equipped to requested slot and false if slot was
|
||||
// changed
|
||||
};
|
||||
|
||||
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
||||
itemPtr = MWBase::Environment::get().getWorldModel()->getPtr(std::get<ObjectId>(item));
|
||||
if (old_it != store.end() && *old_it == itemPtr)
|
||||
return true; // already equipped
|
||||
if (itemPtr.isEmpty() || itemPtr.getRefData().getCount() == 0
|
||||
|| itemPtr.getContainerStore() != static_cast<const MWWorld::ContainerStore*>(&store))
|
||||
{
|
||||
auto old_it = store.getSlot(slot);
|
||||
auto new_it = mEquipment.find(slot);
|
||||
if (new_it == mEquipment.end())
|
||||
{
|
||||
if (old_it != store.end())
|
||||
store.unequipSlot(slot);
|
||||
continue;
|
||||
}
|
||||
if (tryEquipToSlot(slot, new_it->second))
|
||||
usedSlots[slot] = true;
|
||||
Log(Debug::Warning) << "Object" << std::get<ObjectId>(item).toString() << " is not in inventory";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const ESM::RefId& recordId = ESM::RefId::stringRefId(std::get<std::string>(item));
|
||||
if (old_it != store.end() && old_it->getCellRef().getRefId() == recordId)
|
||||
return true; // already equipped
|
||||
itemPtr = store.search(recordId);
|
||||
if (itemPtr.isEmpty() || itemPtr.getRefData().getCount() == 0)
|
||||
{
|
||||
Log(Debug::Warning) << "There is no object with recordId='" << recordId << "' in inventory";
|
||||
return false;
|
||||
}
|
||||
for (const auto& [slot, item] : mEquipment)
|
||||
if (slot >= MWWorld::InventoryStore::Slots)
|
||||
tryEquipToSlot(anySlot, item);
|
||||
}
|
||||
|
||||
std::string toString() const override { return "SetEquipmentAction"; }
|
||||
auto [allowedSlots, _] = itemPtr.getClass().getEquipmentSlots(itemPtr);
|
||||
bool requestedSlotIsAllowed
|
||||
= std::find(allowedSlots.begin(), allowedSlots.end(), slot) != allowedSlots.end();
|
||||
if (!requestedSlotIsAllowed)
|
||||
{
|
||||
auto firstAllowed
|
||||
= std::find_if(allowedSlots.begin(), allowedSlots.end(), [&](int s) { return !usedSlots[s]; });
|
||||
if (firstAllowed == allowedSlots.end())
|
||||
{
|
||||
Log(Debug::Warning) << "No suitable slot for " << itemPtr.toString();
|
||||
return false;
|
||||
}
|
||||
slot = *firstAllowed;
|
||||
}
|
||||
|
||||
private:
|
||||
ObjectId mActor;
|
||||
Equipment mEquipment;
|
||||
// TODO: Refactor InventoryStore to accept Ptr and get rid of this linear search.
|
||||
MWWorld::ContainerStoreIterator it = std::find(store.begin(), store.end(), itemPtr);
|
||||
if (it == store.end()) // should never happen
|
||||
throw std::logic_error("Item not found in container");
|
||||
|
||||
store.equip(slot, it);
|
||||
return requestedSlotIsAllowed; // return true if equipped to requested slot and false if slot was changed
|
||||
};
|
||||
|
||||
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
||||
{
|
||||
auto old_it = store.getSlot(slot);
|
||||
auto new_it = equipment.find(slot);
|
||||
if (new_it == equipment.end())
|
||||
{
|
||||
if (old_it != store.end())
|
||||
store.unequipSlot(slot);
|
||||
continue;
|
||||
}
|
||||
if (tryEquipToSlot(slot, new_it->second))
|
||||
usedSlots[slot] = true;
|
||||
}
|
||||
for (const auto& [slot, item] : equipment)
|
||||
if (slot >= MWWorld::InventoryStore::Slots)
|
||||
tryEquipToSlot(anySlot, item);
|
||||
}
|
||||
|
||||
void addActorBindings(sol::table actor, const Context& context)
|
||||
|
@ -263,13 +240,14 @@ namespace MWLua
|
|||
return store.isEquipped(item.ptr());
|
||||
};
|
||||
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())
|
||||
throw std::runtime_error(obj.toString() + " has no equipment slots");
|
||||
return;
|
||||
}
|
||||
SetEquipmentAction::Equipment eqp;
|
||||
Equipment eqp;
|
||||
for (auto& [key, value] : equipment)
|
||||
{
|
||||
int slot = key.as<int>();
|
||||
|
@ -279,7 +257,7 @@ namespace MWLua
|
|||
eqp[slot] = value.as<std::string>();
|
||||
}
|
||||
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) {
|
||||
const DetourNavigator::AgentBounds agentBounds
|
||||
|
|
|
@ -20,71 +20,20 @@ namespace MWLua
|
|||
{
|
||||
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) }
|
||||
try
|
||||
{
|
||||
fn();
|
||||
}
|
||||
|
||||
void apply() const override
|
||||
catch (...)
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (mType)
|
||||
{
|
||||
case CREATE:
|
||||
mElement->create();
|
||||
break;
|
||||
case UPDATE:
|
||||
mElement->update();
|
||||
break;
|
||||
case DESTROY:
|
||||
mElement->destroy();
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (std::exception&)
|
||||
{
|
||||
// prevent any actions on a potentially corrupted widget
|
||||
mElement->mRoot = nullptr;
|
||||
throw;
|
||||
}
|
||||
// prevent any actions on a potentially corrupted widget
|
||||
element->mRoot = nullptr;
|
||||
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
|
||||
inline size_t fromLuaIndex(size_t i)
|
||||
|
@ -102,17 +51,17 @@ namespace MWLua
|
|||
auto element = context.mLua->sol().new_usertype<LuaUi::Element>("Element");
|
||||
element["layout"] = sol::property([](LuaUi::Element& element) { return element.mLayout; },
|
||||
[](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)
|
||||
return;
|
||||
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)
|
||||
return;
|
||||
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();
|
||||
|
@ -144,9 +93,9 @@ namespace MWLua
|
|||
}
|
||||
};
|
||||
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);
|
||||
context.mLuaManager->addAction(std::make_unique<UiAction>(UiAction::CREATE, element, context.mLua));
|
||||
luaManager->addAction([element] { wrapAction(element, [&] { element->create(); }); }, "Create UI");
|
||||
return element;
|
||||
};
|
||||
api["updateAll"] = [context]() {
|
||||
|
|
Loading…
Reference in a new issue