diff options
Diffstat (limited to '')
-rw-r--r-- | src/Bindings/LuaWindow.h | 72 |
1 files changed, 37 insertions, 35 deletions
diff --git a/src/Bindings/LuaWindow.h b/src/Bindings/LuaWindow.h index 2a16d91ed..f292a5154 100644 --- a/src/Bindings/LuaWindow.h +++ b/src/Bindings/LuaWindow.h @@ -9,8 +9,6 @@ #pragma once -#include <atomic> -#include "LuaState.h" #include "../UI/Window.h" #include "../ItemGrid.h" @@ -18,30 +16,35 @@ +// fwd: PluginLua.h +class cPluginLua; + + + + + /** A window that has been created by a Lua plugin and is handled entirely by that plugin This object needs extra care with its lifetime management: - It is created by Lua, so Lua expects to garbage-collect it later -- Normal cWindow objects are deleted in their ClosedByPlayer() function if the last player closes them - To overcome this, this object overloads the Destroy functions, which doesn't let the ClosedByPlayer() - delete the window, but rather leaves it dangling, with only Lua having the reference to it. -- Lua could GC the window while a player is still using it - The object creates a Lua reference to itself when opened by a player and - removes the reference when the last player closes the window. -*/ +- normal cWindow objects are deleted in their ClosedByPlayer() function if the last player closes them +To overcome this, this object overloads the Destroy functions, which doesn't let the ClosedByPlayer() +delete the window, but rather leaves it dangling, with only Lua having the reference to it. +Additionally, to forbid Lua from deleting this object while it is used by players, the manual bindings for +cPlayer:OpenWindow check if the window is of this class, and if so, make a global Lua reference for this object. +This reference needs to be unreferenced in the Destroy() function. */ // tolua_begin class cLuaWindow : public cWindow // tolua_end , public cItemGrid::cListener -{ // tolua_export - typedef cWindow Super; + // tolua_begin +{ + typedef cWindow super; public: - /** Create a window of the specified type, with a slot grid of a_SlotsX * a_SlotsY size. - Exported in ManualBindings.cpp */ - cLuaWindow(cLuaState & a_LuaState, cWindow::WindowType a_WindowType, int a_SlotsX, int a_SlotsY, const AString & a_Title); + /** Create a window of the specified type, with a slot grid of a_SlotsX * a_SlotsY size */ + cLuaWindow(cWindow::WindowType a_WindowType, int a_SlotsX, int a_SlotsY, const AString & a_Title); - // tolua_begin virtual ~cLuaWindow(); /** Returns the internal representation of the contents that are manipulated by Lua */ @@ -49,37 +52,36 @@ public: // tolua_end - /** Sets the Lua callback function to call when the window is about to close */ - void SetOnClosing(cLuaState::cCallbackPtr a_OnClosing); + /** Sets the plugin reference and the internal Lua object reference index + used for preventing Lua's GC to collect this class while the window is open. */ + void SetLuaRef(cPluginLua * a_Plugin, int a_LuaRef); - /** Sets the Lua callback function to call when a slot is changed */ - void SetOnSlotChanged(cLuaState::cCallbackPtr a_OnSlotChanged); + /** Returns true if SetLuaRef() has been called */ + bool IsLuaReferenced(void) const; -protected: + /** Sets the callback function (Lua reference) to call when the window is about to close */ + void SetOnClosing(cPluginLua * a_Plugin, int a_FnRef); + + /** Sets the callback function (Lua reference) to call when a slot is changed */ + void SetOnSlotChanged(cPluginLua * a_Plugin, int a_FnRef); +protected: /** Contents of the non-inventory part */ cItemGrid m_Contents; - /** The Lua state that has opened the window and owns the m_LuaRef */ - cLuaState * m_LuaState; - - /** The Lua callback to call when the window is closing for any player */ - cLuaState::cCallbackPtr m_OnClosing; - - /** The Lua callback to call when a slot has changed */ - cLuaState::cCallbackPtr m_OnSlotChanged; + /** The plugin that has opened the window and owns the m_LuaRef */ + cPluginLua * m_Plugin; - /** Number of players that are currently using the window. - Used to manager the m_LuaRef lifetime. */ - std::atomic<int> m_PlayerCount; + /** The Lua object reference, used for keeping the object alive as long as any player has the window open */ + int m_LuaRef; - /** Reference to self, to keep Lua from GCing the object while a player is still using it. - Created when the first player opens the window, destroyed when the last player closes the window. */ - cLuaState::cRef m_LuaRef; + /** The Lua reference for the callback to call when the window is closing for any player */ + int m_OnClosingFnRef; + /** The Lua reference for the callback to call when a slot has changed */ + int m_OnSlotChangedFnRef; // cWindow overrides: - virtual void OpenedByPlayer(cPlayer & a_Player) override; virtual bool ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) override; virtual void Destroy(void) override; virtual void DistributeStack(cItem & a_ItemStack, int a_Slot, cPlayer & a_Player, cSlotArea * a_ClickedArea, bool a_ShouldApply) override; |