1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-12-11 09:04:35 +00:00
openmw/apps/openmw/mwlua
uramer 6484e2e411 Merge branch 'serices_are_readonly' into 'master'
Make actor.providedServices read only

See merge request OpenMW/openmw!3570
2023-11-16 15:23:09 +00:00
..
types Make actor.providedServices read only 2023-11-16 15:23:09 +00:00
camerabindings.cpp Use settings values for Video settings 2023-10-27 14:31:23 +02:00
camerabindings.hpp Add headers for all .cpp files in mwlua; move packages initilaization from LuaManager to luabindings.cpp 2023-04-25 23:24:51 +02:00
cellbindings.cpp Add movable static and ESM4 land texture stores 2023-10-27 22:53:40 +03:00
cellbindings.hpp Add headers for all .cpp files in mwlua; move packages initilaization from LuaManager to luabindings.cpp 2023-04-25 23:24:51 +02:00
context.hpp Rename MWLua::WorldView -> MWLua::ObjectLists 2023-08-08 22:57:28 +02:00
debugbindings.cpp Parse navmesh render mode on reading settings 2023-10-01 11:09:59 +02:00
debugbindings.hpp Support rendering for navmesh update frequency as a heatmap 2022-05-17 01:54:20 +02:00
engineevents.cpp Replace const ESM::RefNum& -> ESM::RefNum 2023-09-15 19:38:09 +02:00
engineevents.hpp Add missing argument force in UseItem 2023-09-11 16:21:34 +02:00
factionbindings.cpp small coverity fix 2023-09-13 12:28:38 +02:00
factionbindings.hpp Implement Lua API for factions (feature 7468) 2023-09-12 09:49:03 +04:00
globalscripts.hpp Add missing argument force in UseItem 2023-09-11 16:21:34 +02:00
inputbindings.cpp [Lua] Add CONTROL_SWITCH functions to types.Player and deprecate them in openmw.input 2023-10-10 01:15:09 +02:00
inputbindings.hpp Add headers for all .cpp files in mwlua; move packages initilaization from LuaManager to luabindings.cpp 2023-04-25 23:24:51 +02:00
localscripts.cpp Lua engine handler onTeleported 2023-07-19 10:42:58 +02:00
localscripts.hpp Lua engine handler onTeleported 2023-07-19 10:42:58 +02:00
luabindings.cpp Remove ATTRIBUTE, SKILL, and SCHOOL enums 2023-09-21 19:34:13 +02:00
luabindings.hpp Add headers for all .cpp files in mwlua; move packages initilaization from LuaManager to luabindings.cpp 2023-04-25 23:24:51 +02:00
luaevents.cpp Replace const ESM::RefNum& -> ESM::RefNum 2023-09-15 19:38:09 +02:00
luaevents.hpp Address review comments 2023-03-26 03:38:40 +02:00
luamanagerimp.cpp Fix #7674 2023-11-05 21:32:18 +01:00
luamanagerimp.hpp Fix #7674 2023-11-05 21:32:18 +01:00
magicbindings.cpp Fix #7624 2023-10-14 14:18:50 +02:00
magicbindings.hpp Lua bindings for magic. Based on the work made by @bharbich in !2765. 2023-04-20 18:48:34 +02:00
mwscriptbindings.cpp Fix minor doc error, throw error when attempting to assign a value to a non-existing global variable in lua 2023-11-03 16:31:23 +00:00
mwscriptbindings.hpp Change MWScript Lua bindings (#7142) 2023-06-30 22:26:17 +02:00
nearbybindings.cpp Change FormId::toString to be consistent with RefId. Remove FormIdRefId. 2023-08-27 09:55:06 +02:00
nearbybindings.hpp Add headers for all .cpp files in mwlua; move packages initilaization from LuaManager to luabindings.cpp 2023-04-25 23:24:51 +02:00
object.hpp Replace const ESM::RefNum& -> ESM::RefNum 2023-09-15 19:38:09 +02:00
objectbindings.cpp Add lua binding for gameObject globalVariable 2023-10-24 13:55:50 +00:00
objectbindings.hpp Add headers for all .cpp files in mwlua; move packages initilaization from LuaManager to luabindings.cpp 2023-04-25 23:24:51 +02:00
objectlists.cpp Replace const ESM::RefNum& -> ESM::RefNum 2023-09-15 19:38:09 +02:00
objectlists.hpp Rename MWLua::WorldView -> MWLua::ObjectLists 2023-08-08 22:57:28 +02:00
objectvariant.hpp Add missing type validation in mwlua/objectvariant.hpp 2023-04-23 20:47:24 +02:00
playerscripts.hpp Queue Lua handler uiModeChanged 2023-10-21 13:04:02 +02:00
postprocessingbindings.cpp Move some time-related function from World and WorldView to DateTimeManager 2023-08-08 22:57:28 +02:00
postprocessingbindings.hpp Add headers for all .cpp files in mwlua; move packages initilaization from LuaManager to luabindings.cpp 2023-04-25 23:24:51 +02:00
README.md Add a bit of high-level developer documentation about the Lua system 2023-03-13 22:41:28 +00:00
soundbindings.cpp Add a way to check if sound system is enabled 2023-09-14 13:02:20 +04:00
soundbindings.hpp Implement Lua bindings for sound system 2023-08-15 10:28:29 +04:00
stats.cpp Expose governing attributes to Lua 2023-11-02 17:43:09 +01:00
stats.hpp Expose skill and attribute records to Lua and deprecate their enums 2023-09-07 21:30:08 +02:00
uibindings.cpp Use settings values for Video settings 2023-10-27 14:31:23 +02:00
uibindings.hpp Add headers for all .cpp files in mwlua; move packages initilaization from LuaManager to luabindings.cpp 2023-04-25 23:24:51 +02:00
userdataserializer.cpp Replace const ESM::RefNum& -> ESM::RefNum 2023-09-15 19:38:09 +02:00
userdataserializer.hpp Merge MWLua::ObjectRegistry and MWWorld::WorldModel 2022-12-28 12:45:11 +01:00
vfsbindings.cpp Simplify VFS index iteration 2023-09-02 17:40:14 +04:00
vfsbindings.hpp Implement Lua API for VFS 2023-09-02 08:47:46 +04:00
worker.cpp Catch unhandled exceptions 2023-07-31 16:35:31 +04:00
worker.hpp Move LuaWorker to a separate file 2022-10-06 21:50:31 +02:00

MWLua

This folder contains the C++ implementation of the Lua scripting system.

For user-facing documentation, see OpenMW Lua scripting. The documentation is generated from /docs/source/reference/lua-scripting. You can find instructions for generating the documentation at the root of the docs folder.

The Lua API reference is generated from the specifications in /files/lua_api. They are written in the Lua Development Tool Documentation Language, and also enable autocompletion for (LDT) users. Please update them to reflect any changes you make.

MWLua::LuaManager

The Lua manager is the central interface through which information flows from the engine to the scripts and back.

Lua is executed in a separate thread by default. This thread executes update() in parallel with rendering logic (specifically with OSG Cull traversal). Because of this, Lua must not synchronously mutate anything that can directly or indirectly affect the scene graph. Instead such changes are queued to mActionQueue. They are then processed by synchronizedUpdate(), which is executed by the main thread. The Lua thread is paused while other updates of the game state take place, which means that state that doesn't affect the scene graph can be mutated immediately. There is no easy way to characterize which things affect the graph, you'll need to inspect the code.

Bindings

The bulk of the code in this folder consists of bindings that expose C++ data to Lua.

As explained in the scripting overview, there are Global and Local scripts, and they have different capabilities. A Local script has read-only access to objects other the one it is attached to. The bindings use the types MWLua::GObject, MWLua::LObject, MWLua::SelfObject to enforce this behaviour.

  • MWLua::GObject is used in global scripts
  • MWLua::LObject is used in local scripts (readonly),
  • MWLua::SelfObject is the object the local script is attached to.
  • MWLua::Object is the common base of all 3.

Functions that don't change objects are usually available in both local and global scripts so they accept MWLua::Object. Some (for example setEquipment in actor.cpp) should work only on self and because of this have argument of type SelfObject. There are also cases where a function is available in both local and global scripts, but has different effects in different cases. For example see the binding actor["inventory"] in 'MWLua::addActorBindings` in actor.cpp:

actor["inventory"] = sol::overload([](const LObject& o) { return Inventory<LObject>{ o }; },
    [](const GObject& o) { return Inventory<GObject>{ o }; });

The difference is that Inventory<LObject> is readonly and Inventory<GObject> is mutable. The read-only bindings are defined for both, but some functions are exclusive for Inventory<GObject>.

Mutations that affect the scene graph

Because of the threading issues mentioned under MWLua::LuaManager, bindings that mutate things that affect the scene graph must be implemented by queuing an action with LuaManager::addAction.

Here is an example that illustrates action queuing, along with the differences between GObject and LObject:

// We can always read the value because OSG Cull doesn't modify `RefData`.
auto isEnabled = [](const Object& o) { return o.ptr().getRefData().isEnabled(); };

// Changing the value must be queued because `World::enable`/`World::disable` aside of
// changing `RefData` also adds/removes the object to the scene graph.
auto setEnabled = [context](const Object& object, bool enable) {
    // It is important that the lambda state stores `object` and not the result of
    // `object.ptr()` because when delayed will be executed the old Ptr can potentially
    // be already invalidated.
    context.mLuaManager->addAction([object, enable] {
        if (enable)
            MWBase::Environment::get().getWorld()->enable(object.ptr());
        else
            MWBase::Environment::get().getWorld()->disable(object.ptr());
    });
};

// Local scripts can only view the value (because in multiplayer local scripts
// will be client-side and we want to avoid synchronization issues).
LObjectMetatable["enabled"] = sol::readonly_property(isEnabled);

// Global scripts can both read and modify the value.
GObjectMetatable["enabled"] = sol::property(isEnabled, setEnabled);

Please note that queueing means changes scripts make won't be visible to other scripts before the next frame. If you want to avoid that, you can implement a cache in the bindings. The first write will create the cache and queue the value to be synchronized from the cache to the engine in the next synchronization. Later writes will update the cache. Reads will read the cache if it exists. See LocalScripts::SelfObject::mStatsCache for an example.