From de349962d13f7b283e0480e518fa1810b40720da Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Wed, 14 Apr 2021 00:00:51 +0200 Subject: [PATCH] Engine handlers onActive/onInactive and a function self:isActive() --- apps/openmw/mwlua/localscripts.cpp | 13 +++++++++++++ apps/openmw/mwlua/localscripts.hpp | 9 ++++++++- apps/openmw/mwlua/luamanagerimp.cpp | 19 ++++++++++++++++++- apps/openmw/mwlua/luamanagerimp.hpp | 2 ++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwlua/localscripts.cpp b/apps/openmw/mwlua/localscripts.cpp index 473ffd3fef..4b556faa4d 100644 --- a/apps/openmw/mwlua/localscripts.cpp +++ b/apps/openmw/mwlua/localscripts.cpp @@ -33,6 +33,7 @@ namespace MWLua selfAPI[sol::meta_function::to_string] = [](SelfObject& self) { return "openmw.self[" + self.toString() + "]"; }; selfAPI["object"] = sol::readonly_property([](SelfObject& self) -> LObject { return LObject(self); }); selfAPI["controls"] = sol::readonly_property([](SelfObject& self) { return &self.mControls; }); + selfAPI["isActive"] = [](SelfObject& self) { return &self.mIsActive; }; selfAPI["setDirectControl"] = [](SelfObject& self, bool v) { self.mControls.controlledFromLua = v; }; selfAPI["setEquipment"] = [manager=context.mLuaManager](const SelfObject& obj, sol::table equipment) { @@ -87,6 +88,18 @@ namespace MWLua { mData.mControls.controlledFromLua = false; this->addPackage("openmw.self", sol::make_object(lua->sol(), &mData)); + registerEngineHandlers({&mOnActiveHandlers, &mOnInactiveHandlers}); + } + + void LocalScripts::becomeActive() + { + mData.mIsActive = true; + callEngineHandlers(mOnActiveHandlers); + } + void LocalScripts::becomeInactive() + { + mData.mIsActive = false; + callEngineHandlers(mOnInactiveHandlers); } } diff --git a/apps/openmw/mwlua/localscripts.hpp b/apps/openmw/mwlua/localscripts.hpp index c8d85aad58..a738dfede5 100644 --- a/apps/openmw/mwlua/localscripts.hpp +++ b/apps/openmw/mwlua/localscripts.hpp @@ -26,12 +26,19 @@ namespace MWLua struct SelfObject : public LObject { - SelfObject(const LObject& obj) : LObject(obj) {} + SelfObject(const LObject& obj) : LObject(obj), mIsActive(false) {} MWBase::LuaManager::ActorControls mControls; + bool mIsActive; }; + + void becomeActive(); + void becomeInactive(); protected: LocalScripts(LuaUtil::LuaState* lua, const LObject& obj); SelfObject mData; + private: + EngineHandlerList mOnActiveHandlers{"onActive"}; + EngineHandlerList mOnInactiveHandlers{"onInactive"}; }; } diff --git a/apps/openmw/mwlua/luamanagerimp.cpp b/apps/openmw/mwlua/luamanagerimp.cpp index b961550280..09b3eb6e13 100644 --- a/apps/openmw/mwlua/luamanagerimp.cpp +++ b/apps/openmw/mwlua/luamanagerimp.cpp @@ -44,7 +44,9 @@ namespace MWLua localContext.mSerializer = mLocalSerializer.get(); initObjectBindingsForGlobalScripts(context); + initCellBindingsForGlobalScripts(context); initObjectBindingsForLocalScripts(localContext); + initCellBindingsForLocalScripts(localContext); LocalScripts::initializeSelfPackage(localContext); mLua.addCommonPackage("openmw.async", getAsyncPackageInitializer(context)); @@ -158,6 +160,13 @@ namespace MWLua } mKeyPressEvents.clear(); + for (LocalScripts* localScripts : mObjectInactiveEvents) + localScripts->becomeInactive(); + for (LocalScripts* localScripts : mObjectActiveEvents) + localScripts->becomeActive(); + mObjectActiveEvents.clear(); + mObjectInactiveEvents.clear(); + for (ObjectId id : mActorAddedEvents) mGlobalScripts.actorActive(GObject(id, mWorldView.getObjectRegistry())); mActorAddedEvents.clear(); @@ -190,6 +199,8 @@ namespace MWLua mGlobalEvents.clear(); mKeyPressEvents.clear(); mActorAddedEvents.clear(); + mObjectActiveEvents.clear(); + mObjectInactiveEvents.clear(); mPlayerChanged = false; mPlayerScripts = nullptr; mWorldView.clear(); @@ -207,7 +218,10 @@ namespace MWLua LocalScripts* localScripts = ptr.getRefData().getLuaScripts(); if (localScripts) + { mActiveLocalScripts.insert(localScripts); + mObjectActiveEvents.push_back(localScripts); + } if (ptr.getClass().isActor() && ptr != mPlayer) mActorAddedEvents.push_back(getId(ptr)); @@ -233,7 +247,10 @@ namespace MWLua mWorldView.objectRemovedFromScene(ptr); LocalScripts* localScripts = ptr.getRefData().getLuaScripts(); if (localScripts) + { mActiveLocalScripts.erase(localScripts); + mObjectInactiveEvents.push_back(localScripts); + } // TODO: call mWorldView.objectUnloaded if object is unloaded from memory (does it ever happen?) and ptr becomes invalid. } @@ -242,7 +259,7 @@ namespace MWLua { mKeyPressEvents.push_back(arg.keysym); } - + const MWBase::LuaManager::ActorControls* LuaManager::getActorControls(const MWWorld::Ptr& ptr) const { LocalScripts* localScripts = ptr.getRefData().getLuaScripts(); diff --git a/apps/openmw/mwlua/luamanagerimp.hpp b/apps/openmw/mwlua/luamanagerimp.hpp index 275ee61614..53f2955675 100644 --- a/apps/openmw/mwlua/luamanagerimp.hpp +++ b/apps/openmw/mwlua/luamanagerimp.hpp @@ -94,6 +94,8 @@ namespace MWLua std::vector mKeyPressEvents; std::vector mActorAddedEvents; + std::vector mObjectActiveEvents; + std::vector mObjectInactiveEvents; // Queued actions that should be done in main thread. Processed by applyQueuedChanges(). std::vector> mActionQueue;