Added cLuaWindow:SetOnSlotChanged(); the callback is called only for non-inventory slots

git-svn-id: http://mc-server.googlecode.com/svn/trunk@1535 0a769ca7-a7f5-676a-18bf-c427514a06d6
master
madmaxoft@gmail.com 2013-05-31 07:16:14 +00:00
parent 2eb1240e14
commit bf7c2fe783
6 changed files with 90 additions and 8 deletions

View File

@ -588,9 +588,15 @@ function HandleTestWndCmd(a_Split, a_Player)
return (attempt <= 3); -- refuse twice, then allow return (attempt <= 3); -- refuse twice, then allow
end end
-- Log the slot changes
local OnSlotChanged = function(Window, SlotNum)
LOG("Window \"" .. Window:GetWindowTitle() .. "\" slot " .. SlotNum .. " changed.");
end
local Window = cLuaWindow(WindowType, WindowSizeX, WindowSizeY, "TestWnd"); local Window = cLuaWindow(WindowType, WindowSizeX, WindowSizeY, "TestWnd");
Window:SetSlot(a_Player, 0, cItem(E_ITEM_DIAMOND, 64)); Window:SetSlot(a_Player, 0, cItem(E_ITEM_DIAMOND, 64));
Window:SetOnClosing(OnClosing); Window:SetOnClosing(OnClosing);
Window:SetOnSlotChanged(OnSlotChanged);
a_Player:OpenWindow(Window); a_Player:OpenWindow(Window);

View File

@ -25,6 +25,7 @@ cLuaWindow::cLuaWindow(cWindow::WindowType a_WindowType, int a_SlotsX, int a_Slo
m_OnClosingFnRef(LUA_REFNIL), m_OnClosingFnRef(LUA_REFNIL),
m_OnSlotChangedFnRef(LUA_REFNIL) m_OnSlotChangedFnRef(LUA_REFNIL)
{ {
m_Contents.AddListener(*this);
m_SlotAreas.push_back(new cSlotAreaItemGrid(m_Contents, *this)); m_SlotAreas.push_back(new cSlotAreaItemGrid(m_Contents, *this));
// If appropriate, add an Armor slot area: // If appropriate, add an Armor slot area:
@ -96,6 +97,26 @@ void cLuaWindow::SetOnClosing(cPlugin_NewLua * a_Plugin, int a_FnRef)
void cLuaWindow::SetOnSlotChanged(cPlugin_NewLua * a_Plugin, int a_FnRef)
{
// Either m_Plugin is not set or equal to the passed plugin; only one plugin can use one cLuaWindow object
ASSERT((m_Plugin == NULL) || (m_Plugin == a_Plugin));
// If there already was a function, unreference it first
if (m_OnSlotChangedFnRef != LUA_REFNIL)
{
m_Plugin->Unreference(m_OnSlotChangedFnRef);
}
// Store the new reference
m_Plugin = a_Plugin;
m_OnSlotChangedFnRef = a_FnRef;
}
bool cLuaWindow::ClosedByPlayer(cPlayer & a_Player) bool cLuaWindow::ClosedByPlayer(cPlayer & a_Player)
{ {
// First notify the plugin through the registered callback: // First notify the plugin through the registered callback:
@ -133,3 +154,22 @@ void cLuaWindow::Destroy(void)
void cLuaWindow::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum)
{
if (a_ItemGrid != &m_Contents)
{
ASSERT(!"Invalid ItemGrid in callback");
return;
}
// If an OnSlotChanged callback has been registered, call it:
if (m_OnSlotChangedFnRef != LUA_REFNIL)
{
m_Plugin->CallbackWindowSlotChanged(m_OnSlotChangedFnRef, *this, a_SlotNum);
}
}

View File

@ -10,6 +10,7 @@
#pragma once #pragma once
#include "UI/Window.h" #include "UI/Window.h"
#include "ItemGrid.h"
@ -35,7 +36,8 @@ cPlayer:OpenWindow check if the window is of this class, and if so, make a globa
This reference needs to be unreferenced in the Destroy() function. This reference needs to be unreferenced in the Destroy() function.
*/ */
class cLuaWindow : class cLuaWindow :
public cWindow public cWindow,
public cItemGrid::cListener
{ {
typedef cWindow super; typedef cWindow super;
@ -83,6 +85,9 @@ protected:
// cWindow overrides: // cWindow overrides:
virtual bool ClosedByPlayer(cPlayer & a_Player) override; virtual bool ClosedByPlayer(cPlayer & a_Player) override;
virtual void Destroy(void) override; virtual void Destroy(void) override;
// cItemGrid::cListener overrides:
virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) override;
} ; // tolua_export } ; // tolua_export

View File

@ -938,9 +938,13 @@ static int tolua_cPlayer_OpenWindow(lua_State * tolua_S)
static int tolua_cLuaWindow_SetOnClosing(lua_State * tolua_S) template <
class OBJTYPE,
void (OBJTYPE::*SetCallback)(cPlugin_NewLua * a_Plugin, int a_FnRef)
>
static int tolua_SetObjectCallback(lua_State * tolua_S)
{ {
// Function signature: cPlayer:SetOnClosing(CallbackFunction) // Function signature: OBJTYPE:SetWhateverCallback(CallbackFunction)
// Retrieve the plugin instance from the Lua state // Retrieve the plugin instance from the Lua state
cPlugin_NewLua * Plugin = GetLuaPlugin(tolua_S); cPlugin_NewLua * Plugin = GetLuaPlugin(tolua_S);
@ -950,14 +954,14 @@ static int tolua_cLuaWindow_SetOnClosing(lua_State * tolua_S)
return 0; return 0;
} }
// Get the parameters: // Get the parameters - self and the function reference:
cLuaWindow * self = (cLuaWindow *)tolua_tousertype(tolua_S, 1, NULL); OBJTYPE * self = (OBJTYPE *)tolua_tousertype(tolua_S, 1, NULL);
if (self == NULL) if (self == NULL)
{ {
LOGWARNING("%s: invalid self (%p)", __FUNCTION__, self); LOGWARNING("%s: invalid self (%p)", __FUNCTION__, self);
return 0; return 0;
} }
int FnRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); // Store function reference int FnRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); // Store function reference for later retrieval
if (FnRef == LUA_REFNIL) if (FnRef == LUA_REFNIL)
{ {
LOGERROR("%s: Cannot create a function reference. Callback not set.", __FUNCTION__); LOGERROR("%s: Cannot create a function reference. Callback not set.", __FUNCTION__);
@ -965,7 +969,7 @@ static int tolua_cLuaWindow_SetOnClosing(lua_State * tolua_S)
} }
// Set the callback // Set the callback
self->SetOnClosing(Plugin, FnRef); (self->*SetCallback)(Plugin, FnRef);
return 0; return 0;
} }
@ -1301,7 +1305,8 @@ void ManualBindings::Bind( lua_State* tolua_S )
tolua_endmodule(tolua_S); tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cLuaWindow"); tolua_beginmodule(tolua_S, "cLuaWindow");
tolua_function(tolua_S, "SetOnClosing", tolua_cLuaWindow_SetOnClosing); tolua_function(tolua_S, "SetOnClosing", tolua_SetObjectCallback<cLuaWindow, &cLuaWindow::SetOnClosing>);
tolua_function(tolua_S, "SetOnSlotChanged", tolua_SetObjectCallback<cLuaWindow, &cLuaWindow::SetOnSlotChanged>);
tolua_endmodule(tolua_S); tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cPlugin_NewLua"); tolua_beginmodule(tolua_S, "cPlugin_NewLua");

View File

@ -1667,6 +1667,8 @@ void cPlugin_NewLua::Unreference(int a_LuaRef)
bool cPlugin_NewLua::CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPlayer & a_Player) bool cPlugin_NewLua::CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPlayer & a_Player)
{ {
ASSERT(a_FnRef != LUA_REFNIL);
cCSLock Lock(m_CriticalSection); cCSLock Lock(m_CriticalSection);
lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, a_FnRef); // Push the function to be called lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, a_FnRef); // Push the function to be called
tolua_pushusertype(m_LuaState, &a_Window, "cWindow"); tolua_pushusertype(m_LuaState, &a_Window, "cWindow");
@ -1689,6 +1691,27 @@ bool cPlugin_NewLua::CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPla
void cPlugin_NewLua::CallbackWindowSlotChanged(int a_FnRef, cWindow & a_Window, int a_SlotNum)
{
ASSERT(a_FnRef != LUA_REFNIL);
cCSLock Lock(m_CriticalSection);
lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, a_FnRef); // Push the function to be called
tolua_pushusertype(m_LuaState, &a_Window, "cWindow");
tolua_pushnumber (m_LuaState, a_SlotNum);
// Call function:
int s = lua_pcall(m_LuaState, 2, 0, 0);
if (report_errors(m_LuaState, s))
{
LOGERROR("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState));
}
}
// Helper functions // Helper functions
bool cPlugin_NewLua::PushFunction(const char * a_FunctionName, bool a_bLogError /* = true */) bool cPlugin_NewLua::PushFunction(const char * a_FunctionName, bool a_bLogError /* = true */)
{ {

View File

@ -108,6 +108,9 @@ public:
/// Calls the plugin-specified "cLuaWindow closing" callback. Returns true only if the callback returned true /// Calls the plugin-specified "cLuaWindow closing" callback. Returns true only if the callback returned true
bool CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPlayer & a_Player); bool CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPlayer & a_Player);
/// Calls the plugin-specified "cLuaWindow slot changed" callback.
void CallbackWindowSlotChanged(int a_FnRef, cWindow & a_Window, int a_SlotNum);
protected: protected:
cCriticalSection m_CriticalSection; cCriticalSection m_CriticalSection;
lua_State * m_LuaState; lua_State * m_LuaState;