Added: #1471 CLuaManager, Singleton for the Lua state, the code parts that depend on a globally available Lua state now depend on this instead of CInterfaceManager. Also refactored the code so it's ready to be moved to the NELGUI lib.

This commit is contained in:
dfighter1985 2012-05-23 02:41:43 +02:00
parent 0d0fe51a0d
commit 4db9e47d13
28 changed files with 978 additions and 980 deletions

View file

@ -99,6 +99,7 @@
#include "interface_v3/people_interraction.h" #include "interface_v3/people_interraction.h"
#include "far_tp.h" #include "far_tp.h"
#include "zone_util.h" #include "zone_util.h"
#include "interface_v3/lua_manager.h"
// //
@ -5146,7 +5147,7 @@ NLMISC_COMMAND(luaObject, "Dump the content of a lua object", "<table name> [max
pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg)); pIM->displaySystemInfo( LuaHelperStuff::formatLuaErrorSysInfo(LUADebugNotEnabledMsg));
return false; return false;
} }
CLuaState *luaState = pIM->getLuaState(); CLuaState *luaState = CLuaManager::getInstance().getLuaState();
if (!luaState) return false; if (!luaState) return false;
CLuaStackChecker lsc(luaState); CLuaStackChecker lsc(luaState);
// get the table // get the table

View file

@ -45,6 +45,7 @@ using namespace NLGUI;
#include "character_cl.h" #include "character_cl.h"
#include "r2/editor.h" #include "r2/editor.h"
#include "r2/dmc/client_edition_module.h" #include "r2/dmc/client_edition_module.h"
#include "interface_v3/lua_manager.h"
/////////// ///////////
// USING // // USING //
@ -327,7 +328,7 @@ void displayStreamingDebug ()
SpfGraph.addOneValue (1000.f*(float)deltaTime); SpfGraph.addOneValue (1000.f*(float)deltaTime);
// lua memory // lua memory
LuaMemGraph.addOneValue(CInterfaceManager::getInstance()->getLuaState()->getGCCount() / 1024.f); LuaMemGraph.addOneValue(CLuaManager::getInstance().getLuaState()->getGCCount() / 1024.f);
// Count of waitinf instance // Count of waitinf instance
CurrentTaskGraph.addOneValue (CAsyncFileManager::getInstance().isTaskRunning()?1.f:0.f); CurrentTaskGraph.addOneValue (CAsyncFileManager::getInstance().isTaskRunning()?1.f:0.f);

View file

@ -104,6 +104,7 @@
#include "landscape_poly_drawer.h" #include "landscape_poly_drawer.h"
#include "session_browser_impl.h" #include "session_browser_impl.h"
#include "interface_v3/lua_manager.h"
// ProgressBar steps in init main loop // ProgressBar steps in init main loop
@ -1320,7 +1321,7 @@ void initMainLoop()
// init CSessionBrowserImpl // init CSessionBrowserImpl
CSessionBrowserImpl::getInstance().init(CInterfaceManager::getInstance()->getLuaState()); CSessionBrowserImpl::getInstance().init(CLuaManager::getInstance().getLuaState());
// active/desactive welcome window // active/desactive welcome window
initWelcomeWindow(); initWelcomeWindow();

View file

@ -23,6 +23,7 @@
#include "group_menu.h" #include "group_menu.h"
#include "lua_ihm.h" #include "lua_ihm.h"
#include "lua_ihm_ryzom.h"
using namespace NLMISC; using namespace NLMISC;
using namespace std; using namespace std;
@ -916,7 +917,7 @@ int CCtrlScroll::luaEnsureVisible(CLuaState &ls)
{ {
const char *funcName = "ensureVisible"; const char *funcName = "ensureVisible";
CLuaIHM::checkArgCount(ls, funcName, 3); CLuaIHM::checkArgCount(ls, funcName, 3);
CLuaIHM::checkArgTypeUIElement(ls, funcName, 1); CLuaIHMRyzom::checkArgTypeUIElement(ls, funcName, 1);
CLuaIHM::checkArgType(ls, funcName, 2, LUA_TSTRING); CLuaIHM::checkArgType(ls, funcName, 2, LUA_TSTRING);
CLuaIHM::checkArgType(ls, funcName, 3, LUA_TSTRING); CLuaIHM::checkArgType(ls, funcName, 3, LUA_TSTRING);
THotSpot hs[2]; THotSpot hs[2];
@ -967,7 +968,7 @@ int CCtrlScroll::luaEnsureVisible(CLuaState &ls)
} }
} }
} }
ensureVisible(CLuaIHM::getUIOnStack(ls, 1), hs[0], hs[1]); ensureVisible(CLuaIHMRyzom::getUIOnStack(ls, 1), hs[0], hs[1]);
return 0; return 0;
} }

View file

@ -27,6 +27,7 @@
#include "view_text_id.h" #include "view_text_id.h"
#include "group_container.h" #include "group_container.h"
#include "lua_ihm.h" #include "lua_ihm.h"
#include "lua_ihm_ryzom.h"
// *************************************************************************** // ***************************************************************************
@ -548,7 +549,7 @@ int CCtrlTextButton::luaGetViewText(CLuaState &ls)
{ {
const char *funcName = "getViewText"; const char *funcName = "getViewText";
CLuaIHM::checkArgCount(ls, funcName, 0); CLuaIHM::checkArgCount(ls, funcName, 0);
CLuaIHM::pushUIOnStack(ls, getViewText()); CLuaIHMRyzom::pushUIOnStack(ls, getViewText());
return 1; return 1;
} }

View file

@ -45,10 +45,13 @@
#include "../client_sheets/sphrase_sheet.h" #include "../client_sheets/sphrase_sheet.h"
#include "nel/misc/xml_auto_ptr.h" #include "nel/misc/xml_auto_ptr.h"
#include "lua_ihm.h" #include "lua_ihm.h"
#include "lua_ihm_ryzom.h"
#include "game_share/bot_chat_types.h" #include "game_share/bot_chat_types.h"
#include "../r2/editor.h" #include "../r2/editor.h"
#include "lua_manager.h"
extern CSheetManager SheetMngr; extern CSheetManager SheetMngr;
using namespace std; using namespace std;
@ -101,7 +104,7 @@ ucstring CControlSheetTooltipInfoWaiter::infoValidated(CDBCtrlSheet* ctrlSheet,
// delegate setup of context he help ( & window ) to lua // delegate setup of context he help ( & window ) to lua
CInterfaceManager *im = CInterfaceManager::getInstance(); CInterfaceManager *im = CInterfaceManager::getInstance();
CLuaState *ls= im->getLuaState(); CLuaState *ls= CLuaManager::getInstance().getLuaState();
{ {
CLuaStackRestorer lsr(ls, 0); CLuaStackRestorer lsr(ls, 0);
@ -128,7 +131,7 @@ ucstring CControlSheetTooltipInfoWaiter::infoValidated(CDBCtrlSheet* ctrlSheet,
// *************************************************************************** // ***************************************************************************
int CDBCtrlSheet::luaGetDraggedSheet(CLuaState &ls) int CDBCtrlSheet::luaGetDraggedSheet(CLuaState &ls)
{ {
CLuaIHM::pushUIOnStack(ls, dynamic_cast<CInterfaceElement *>(_LastDraggedSheet)); CLuaIHMRyzom::pushUIOnStack(ls, dynamic_cast<CInterfaceElement *>(_LastDraggedSheet));
return 1; return 1;
} }
@ -3160,7 +3163,7 @@ void CDBCtrlSheet::getContextHelp(ucstring &help) const
{ {
// delegate setup of context he help ( & window ) to lua // delegate setup of context he help ( & window ) to lua
CInterfaceManager *im = CInterfaceManager::getInstance(); CInterfaceManager *im = CInterfaceManager::getInstance();
CLuaState *ls= im->getLuaState(); CLuaState *ls= CLuaManager::getInstance().getLuaState();
{ {
CLuaStackRestorer lsr(ls, 0); CLuaStackRestorer lsr(ls, 0);
CSPhraseManager *pPM= CSPhraseManager::getInstance(); CSPhraseManager *pPM= CSPhraseManager::getInstance();

View file

@ -26,8 +26,7 @@
#include "view_text_id.h" #include "view_text_id.h"
#include "group_container.h" #include "group_container.h"
#include "lua_ihm.h" #include "lua_ihm.h"
#include "lua_ihm_ryzom.h"
#include "lua_ihm.h"
#include "nel/misc/xml_auto_ptr.h" #include "nel/misc/xml_auto_ptr.h"
@ -916,7 +915,7 @@ sint32 CGroupList::getElementIndex(CViewBase* child) const
int CGroupList::luaGetElementIndex(CLuaState &ls) int CGroupList::luaGetElementIndex(CLuaState &ls)
{ {
CLuaIHM::checkArgCount(ls, "getElementIndex", 1); CLuaIHM::checkArgCount(ls, "getElementIndex", 1);
CViewBase * viewBase = dynamic_cast<CViewBase *>(CLuaIHM::getUIOnStack(ls, 1)); CViewBase * viewBase = dynamic_cast<CViewBase *>(CLuaIHMRyzom::getUIOnStack(ls, 1));
ls.push((double) getElementIndex(viewBase)); ls.push((double) getElementIndex(viewBase));
return 1; return 1;
} }
@ -968,7 +967,7 @@ void CGroupList::swapChildren(uint index1, uint index2)
int CGroupList::luaUpChild(CLuaState &ls) int CGroupList::luaUpChild(CLuaState &ls)
{ {
CLuaIHM::checkArgCount(ls, "upChild", 1); CLuaIHM::checkArgCount(ls, "upChild", 1);
CViewBase * viewBase = dynamic_cast<CViewBase *>(CLuaIHM::getUIOnStack(ls, 1)); CViewBase * viewBase = dynamic_cast<CViewBase *>(CLuaIHMRyzom::getUIOnStack(ls, 1));
sint32 indexUpChild = getElementIndex(viewBase); sint32 indexUpChild = getElementIndex(viewBase);
if(indexUpChild > 0) if(indexUpChild > 0)
{ {
@ -981,7 +980,7 @@ int CGroupList::luaUpChild(CLuaState &ls)
int CGroupList::luaDownChild(CLuaState &ls) int CGroupList::luaDownChild(CLuaState &ls)
{ {
CLuaIHM::checkArgCount(ls, "downChild", 1); CLuaIHM::checkArgCount(ls, "downChild", 1);
CViewBase * viewBase = dynamic_cast<CViewBase *>(CLuaIHM::getUIOnStack(ls, 1)); CViewBase * viewBase = dynamic_cast<CViewBase *>(CLuaIHMRyzom::getUIOnStack(ls, 1));
sint32 indexDownChild = getElementIndex(viewBase); sint32 indexDownChild = getElementIndex(viewBase);
if(indexDownChild < (sint32) (_Elements.size()-1)) if(indexDownChild < (sint32) (_Elements.size()-1))
{ {
@ -1002,7 +1001,7 @@ int CGroupList::luaGetChild(CLuaState &ls)
CLuaIHM::fails(ls, "getChild : trying to access element %d in list '%s', which has %d elements", CLuaIHM::fails(ls, "getChild : trying to access element %d in list '%s', which has %d elements",
index, getId().c_str(), (int) _Elements.size()); index, getId().c_str(), (int) _Elements.size());
} }
CLuaIHM::pushUIOnStack(ls, getChild((uint) index)); CLuaIHMRyzom::pushUIOnStack(ls, getChild((uint) index));
return 1; return 1;
} }
@ -1091,7 +1090,7 @@ int CGroupList::luaAddChild(CLuaState &ls)
{ {
const char *funcName = "addChild"; const char *funcName = "addChild";
CLuaIHM::checkArgCount(ls, funcName, 1); CLuaIHM::checkArgCount(ls, funcName, 1);
CViewBase *vb = dynamic_cast<CViewBase *>(CLuaIHM::getUIOnStack(ls, 1)); CViewBase *vb = dynamic_cast<CViewBase *>(CLuaIHMRyzom::getUIOnStack(ls, 1));
if (!vb) if (!vb)
{ {
CLuaIHM::fails(ls, "%s requires a view, group or control", funcName); CLuaIHM::fails(ls, "%s requires a view, group or control", funcName);
@ -1109,7 +1108,7 @@ int CGroupList::luaAddChildAtIndex(CLuaState &ls)
const char *funcName = "addChildAtIndex"; const char *funcName = "addChildAtIndex";
CLuaIHM::checkArgCount(ls, funcName, 2); CLuaIHM::checkArgCount(ls, funcName, 2);
CLuaIHM::checkArgType(ls, funcName, 2, LUA_TNUMBER); CLuaIHM::checkArgType(ls, funcName, 2, LUA_TNUMBER);
CViewBase *vb = dynamic_cast<CViewBase *>(CLuaIHM::getUIOnStack(ls, 1)); CViewBase *vb = dynamic_cast<CViewBase *>(CLuaIHMRyzom::getUIOnStack(ls, 1));
if (!vb) if (!vb)
{ {
CLuaIHM::fails(ls, "%s requires a view, group or control", funcName); CLuaIHM::fails(ls, "%s requires a view, group or control", funcName);
@ -1126,7 +1125,7 @@ int CGroupList::luaDetachChild(CLuaState &ls)
{ {
const char *funcName = "detachChild"; const char *funcName = "detachChild";
CLuaIHM::checkArgCount(ls, funcName, 1); CLuaIHM::checkArgCount(ls, funcName, 1);
CViewBase *vb = dynamic_cast<CViewBase *>(CLuaIHM::getUIOnStack(ls, 1)); CViewBase *vb = dynamic_cast<CViewBase *>(CLuaIHMRyzom::getUIOnStack(ls, 1));
if (!vb) if (!vb)
{ {
nlwarning("%s requires a view, group or control", funcName); nlwarning("%s requires a view, group or control", funcName);
@ -1143,7 +1142,7 @@ int CGroupList::luaDetachChild(CLuaState &ls)
int CGroupList::luaDelChild(CLuaState &ls) int CGroupList::luaDelChild(CLuaState &ls)
{ {
CLuaIHM::checkArgCount(ls, "CGroupList::delChild", 1); CLuaIHM::checkArgCount(ls, "CGroupList::delChild", 1);
CViewBase *vb = dynamic_cast<CViewBase *>(CLuaIHM::getUIOnStack(ls, 1)); CViewBase *vb = dynamic_cast<CViewBase *>(CLuaIHMRyzom::getUIOnStack(ls, 1));
if (vb) delChild(vb); if (vb) delChild(vb);
updateCoords(); updateCoords();
return 0; return 0;

View file

@ -25,6 +25,7 @@
#include "view_bitmap.h" #include "view_bitmap.h"
#include "action_handler.h" // Just for getAllParams #include "action_handler.h" // Just for getAllParams
#include "lua_ihm.h" #include "lua_ihm.h"
#include "lua_ihm_ryzom.h"
#include "nel/misc/i18n.h" #include "nel/misc/i18n.h"
@ -1692,7 +1693,7 @@ int CGroupSubMenu::luaGetSubMenu(CLuaState &ls)
const char *funcName = "getSubMenu"; const char *funcName = "getSubMenu";
CLuaIHM::checkArgCount(ls, funcName, 1); CLuaIHM::checkArgCount(ls, funcName, 1);
CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
CLuaIHM::pushUIOnStack(ls, getSubMenu((uint) ls.toNumber(1))); CLuaIHMRyzom::pushUIOnStack(ls, getSubMenu((uint) ls.toNumber(1)));
return 1; return 1;
} }
@ -1703,7 +1704,7 @@ int CGroupSubMenu::luaAddSubMenu(CLuaState &ls)
CLuaIHM::checkArgCount(ls, funcName, 1); CLuaIHM::checkArgCount(ls, funcName, 1);
CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
setSubMenu((uint) ls.toNumber(1), new CGroupSubMenu(CViewText::TCtorParam())); setSubMenu((uint) ls.toNumber(1), new CGroupSubMenu(CViewText::TCtorParam()));
CLuaIHM::pushUIOnStack(ls, getSubMenu((uint) ls.toNumber(1))); CLuaIHMRyzom::pushUIOnStack(ls, getSubMenu((uint) ls.toNumber(1)));
return 1; return 1;
} }
@ -1803,11 +1804,11 @@ int CGroupSubMenu::luaSetUserGroupRight(CLuaState &ls)
const char *funcName = "setUserGroupRight"; const char *funcName = "setUserGroupRight";
CLuaIHM::checkArgCount(ls, funcName, 2); CLuaIHM::checkArgCount(ls, funcName, 2);
CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
if (!(CLuaIHM::isUIOnStack(ls, 2) || ls.isNil(2))) if (!(CLuaIHMRyzom::isUIOnStack(ls, 2) || ls.isNil(2)))
{ {
CLuaIHM::fails(ls, "%s : Group required as argument 2", funcName); CLuaIHM::fails(ls, "%s : Group required as argument 2", funcName);
} }
CInterfaceElement *el = CLuaIHM::getUIOnStack(ls, 2); CInterfaceElement *el = CLuaIHMRyzom::getUIOnStack(ls, 2);
CInterfaceGroup *group = dynamic_cast<CInterfaceGroup *>(el); CInterfaceGroup *group = dynamic_cast<CInterfaceGroup *>(el);
if (el && !group) if (el && !group)
{ {
@ -1823,11 +1824,11 @@ int CGroupSubMenu::luaSetUserGroupLeft(CLuaState &ls)
const char *funcName = "setUserGroupLeft"; const char *funcName = "setUserGroupLeft";
CLuaIHM::checkArgCount(ls, funcName, 2); CLuaIHM::checkArgCount(ls, funcName, 2);
CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
if (!(CLuaIHM::isUIOnStack(ls, 2) || ls.isNil(2))) if (!(CLuaIHMRyzom::isUIOnStack(ls, 2) || ls.isNil(2)))
{ {
CLuaIHM::fails(ls, "%s : Group required as argument 2", funcName); CLuaIHM::fails(ls, "%s : Group required as argument 2", funcName);
} }
CInterfaceElement *el = CLuaIHM::getUIOnStack(ls, 2); CInterfaceElement *el = CLuaIHMRyzom::getUIOnStack(ls, 2);
CInterfaceGroup *group = dynamic_cast<CInterfaceGroup *>(el); CInterfaceGroup *group = dynamic_cast<CInterfaceGroup *>(el);
if (el && !group) if (el && !group)
{ {
@ -1844,7 +1845,7 @@ int CGroupSubMenu::luaGetUserGroupRight(CLuaState &ls)
const char *funcName = "getUserGroupRight"; const char *funcName = "getUserGroupRight";
CLuaIHM::checkArgCount(ls, funcName, 1); CLuaIHM::checkArgCount(ls, funcName, 1);
CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
CLuaIHM::pushUIOnStack(ls, getUserGroupRight((uint) ls.toNumber(1))); CLuaIHMRyzom::pushUIOnStack(ls, getUserGroupRight((uint) ls.toNumber(1)));
return 1; return 1;
} }
@ -1858,7 +1859,7 @@ int CGroupSubMenu::luaGetUserGroupLeft(CLuaState &ls)
CInterfaceElement *pIE = getUserGroupLeft((uint) ls.toNumber(1)); CInterfaceElement *pIE = getUserGroupLeft((uint) ls.toNumber(1));
if (pIE) if (pIE)
{ {
CLuaIHM::pushUIOnStack(ls, pIE); CLuaIHMRyzom::pushUIOnStack(ls, pIE);
return 1; return 1;
} }
else return 0; else return 0;
@ -2281,7 +2282,7 @@ void CGroupMenu::setUserGroupLeft(uint line, CInterfaceGroup *gr, bool ownerShip
int CGroupMenu::luaGetRootMenu(CLuaState &ls) int CGroupMenu::luaGetRootMenu(CLuaState &ls)
{ {
CLuaIHM::checkArgCount(ls, "getRootMenu", 0); CLuaIHM::checkArgCount(ls, "getRootMenu", 0);
CLuaIHM::pushUIOnStack(ls, getRootMenu()); CLuaIHMRyzom::pushUIOnStack(ls, getRootMenu());
return 1; return 1;
} }

View file

@ -24,6 +24,7 @@
#include "interface_manager.h" #include "interface_manager.h"
#include "lua_ihm.h" #include "lua_ihm.h"
#include "lua_ihm_ryzom.h"
using namespace std; using namespace std;
@ -234,7 +235,7 @@ void CGroupTab::addTab(CCtrlTabButton * tabB, sint index)
int CGroupTab::luaAddTab(CLuaState &ls) int CGroupTab::luaAddTab(CLuaState &ls)
{ {
CLuaIHM::checkArgCount(ls, "CGroupTab::addTab", 1); CLuaIHM::checkArgCount(ls, "CGroupTab::addTab", 1);
CCtrlTabButton *tabB = dynamic_cast<CCtrlTabButton *>(CLuaIHM::getUIOnStack(ls, 1)); CCtrlTabButton *tabB = dynamic_cast<CCtrlTabButton *>(CLuaIHMRyzom::getUIOnStack(ls, 1));
if (tabB) if (tabB)
{ {
// don't use addTab to avoid selection of new tab // don't use addTab to avoid selection of new tab
@ -259,7 +260,7 @@ int CGroupTab::luaAddTabWithOrder(CLuaState &ls)
CLuaIHM::checkArgCount(ls, funcName, 2); CLuaIHM::checkArgCount(ls, funcName, 2);
CLuaIHM::checkArgType(ls, funcName, 2, LUA_TNUMBER); CLuaIHM::checkArgType(ls, funcName, 2, LUA_TNUMBER);
CCtrlTabButton *tabB = dynamic_cast<CCtrlTabButton *>(CLuaIHM::getUIOnStack(ls, 1)); CCtrlTabButton *tabB = dynamic_cast<CCtrlTabButton *>(CLuaIHMRyzom::getUIOnStack(ls, 1));
if (tabB) if (tabB)
{ {
// don't use addTab to avoid selection of new tab // don't use addTab to avoid selection of new tab
@ -394,7 +395,7 @@ int CGroupTab::luaGetTabButton(CLuaState &ls)
CCtrlTabButton* tab = getTabButton((uint) ls.toNumber(1)); CCtrlTabButton* tab = getTabButton((uint) ls.toNumber(1));
if(tab != NULL) if(tab != NULL)
{ {
CLuaIHM::pushUIOnStack(ls, tab); CLuaIHMRyzom::pushUIOnStack(ls, tab);
return 1; return 1;
} }
return 0; return 0;
@ -725,7 +726,7 @@ int CGroupTab::luaGetGroup(CLuaState &ls)
CInterfaceGroup* group = getGroup((uint) ls.toNumber(1)); CInterfaceGroup* group = getGroup((uint) ls.toNumber(1));
if(group != NULL) if(group != NULL)
{ {
CLuaIHM::pushUIOnStack(ls, group); CLuaIHMRyzom::pushUIOnStack(ls, group);
return 1; return 1;
} }
return 0; return 0;

View file

@ -26,6 +26,7 @@
#include "group_container.h" #include "group_container.h"
#include "action_handler.h" #include "action_handler.h"
#include "lua_ihm.h" #include "lua_ihm.h"
#include "lua_ihm_ryzom.h"
#include "nel/misc/i_xml.h" #include "nel/misc/i_xml.h"
#include "nel/misc/i18n.h" #include "nel/misc/i18n.h"
@ -1490,7 +1491,7 @@ int CGroupTree::SNode::luaGetParentTree(CLuaState &ls)
CLuaIHM::checkArgCount(ls, "getParentTree", 0); CLuaIHM::checkArgCount(ls, "getParentTree", 0);
if (ParentTree) if (ParentTree)
{ {
CLuaIHM::pushUIOnStack(ls, ParentTree); CLuaIHMRyzom::pushUIOnStack(ls, ParentTree);
} }
else else
{ {

View file

@ -26,6 +26,7 @@
#include "interface_link.h" #include "interface_link.h"
#include "nel/misc/xml_auto_ptr.h" #include "nel/misc/xml_auto_ptr.h"
#include "lua_ihm.h" #include "lua_ihm.h"
#include "lua_ihm_ryzom.h"
#include "nel/misc/mem_stream.h" #include "nel/misc/mem_stream.h"
// //
@ -34,29 +35,6 @@ using namespace NLMISC;
CStringMapper *_UIStringMapper = NULL; CStringMapper *_UIStringMapper = NULL;
// ------------------------------------------------------------------------------------------------
CReflectableRefPtrTarget::~CReflectableRefPtrTarget()
{
CInterfaceManager *pIM= CInterfaceManager::getInstance();
CLuaState *lua= pIM->getLuaState();
if(!lua) return;
CLuaStackChecker lsc(lua);
// remove from the lua registry if i'm in
lua->pushLightUserData((void *) this);
lua->getTable(LUA_REGISTRYINDEX);
if (!lua->isNil(-1))
{
lua->pop();
lua->pushLightUserData((void *) this);
lua->pushNil();
lua->setTable(LUA_REGISTRYINDEX);
}
else
{
lua->pop();
}
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
CInterfaceElement::~CInterfaceElement() CInterfaceElement::~CInterfaceElement()
{ {
@ -1198,7 +1176,7 @@ int CInterfaceElement::luaSetPosRef(CLuaState &ls)
int CInterfaceElement::luaSetParentPos(CLuaState &ls) int CInterfaceElement::luaSetParentPos(CLuaState &ls)
{ {
CLuaIHM::checkArgCount(ls, "setParentPos", 1); CLuaIHM::checkArgCount(ls, "setParentPos", 1);
CInterfaceElement *ie = CLuaIHM::getUIOnStack(ls, 1); CInterfaceElement *ie = CLuaIHMRyzom::getUIOnStack(ls, 1);
if(ie) if(ie)
{ {
setParentPos(ie); setParentPos(ie);

View file

@ -80,19 +80,6 @@ public:
}; };
/** Reflectable refcounted object
* NB nico : added this intermediate class so that the binding from lua to the reflection
* system that are found in CLuaIHM can be reused for other objects as well
* NOTE: The class is named 'CReflectableRefPtrTarget' and not 'CReflectableRefCount'
* because the refcount part is only used for ref pointing in the ui
*/
class CReflectableRefPtrTarget : public CReflectable, public NLMISC::CRefCount
{
public:
virtual ~CReflectableRefPtrTarget();
};
#define DECLARE_UI_CLASS(_class_) \ #define DECLARE_UI_CLASS(_class_) \
virtual std::string getClassName() {return #_class_;} \ virtual std::string getClassName() {return #_class_;} \
static NLMISC::IClassable *creator() {return new _class_(CViewBase::TCtorParam());} static NLMISC::IClassable *creator() {return new _class_(CViewBase::TCtorParam());}

View file

@ -25,9 +25,11 @@
#include "group_editbox.h" #include "group_editbox.h"
#include "group_scrolltext.h" #include "group_scrolltext.h"
#include "lua_ihm.h" #include "lua_ihm.h"
#include "lua_ihm_ryzom.h"
#include "nel/misc/stream.h" #include "nel/misc/stream.h"
#include "lua_manager.h"
using namespace std; using namespace std;
using namespace NL3D; using namespace NL3D;
@ -445,7 +447,7 @@ void CInterfaceGroup::addGroup (CInterfaceGroup *child, sint eltOrder /*= -1*/)
int CInterfaceGroup::luaAddGroup (CLuaState &ls) int CInterfaceGroup::luaAddGroup (CLuaState &ls)
{ {
CLuaIHM::checkArgCount(ls, "CInterfaceGroup::addTab", 1); CLuaIHM::checkArgCount(ls, "CInterfaceGroup::addTab", 1);
CInterfaceGroup * group = dynamic_cast<CInterfaceGroup *>(CLuaIHM::getUIOnStack(ls, 1)); CInterfaceGroup * group = dynamic_cast<CInterfaceGroup *>(CLuaIHMRyzom::getUIOnStack(ls, 1));
if(group) if(group)
{ {
group->setParent(this); group->setParent(this);
@ -616,7 +618,7 @@ bool CInterfaceGroup::delGroup (CInterfaceGroup *child, bool dontDelete /* = fal
int CInterfaceGroup::luaDelGroup (CLuaState &ls) int CInterfaceGroup::luaDelGroup (CLuaState &ls)
{ {
CLuaIHM::checkArgCount(ls, "CInterfaceGroup::delTab", 1); CLuaIHM::checkArgCount(ls, "CInterfaceGroup::delTab", 1);
CInterfaceGroup * group = dynamic_cast<CInterfaceGroup *>(CLuaIHM::getUIOnStack(ls, 1)); CInterfaceGroup * group = dynamic_cast<CInterfaceGroup *>(CLuaIHMRyzom::getUIOnStack(ls, 1));
if(group) if(group)
{ {
delGroup(group); delGroup(group);
@ -643,7 +645,7 @@ int CInterfaceGroup::luaGetGroup(CLuaState &ls)
{ {
CLuaIHM::fails(ls, "getGroup : try to index group %s, but there are only %d son groups", ls.toString(1), (int) _ChildrenGroups.size()); CLuaIHM::fails(ls, "getGroup : try to index group %s, but there are only %d son groups", ls.toString(1), (int) _ChildrenGroups.size());
} }
CLuaIHM::pushUIOnStack(ls, _ChildrenGroups[index]); CLuaIHMRyzom::pushUIOnStack(ls, _ChildrenGroups[index]);
return 1; return 1;
} }
@ -1747,7 +1749,7 @@ void CInterfaceGroup::onFrameUpdateWindowPos(sint dx, sint dy)
void CInterfaceGroup::pushLUAEnvTable() void CInterfaceGroup::pushLUAEnvTable()
{ {
CInterfaceManager *pIM= CInterfaceManager::getInstance(); CInterfaceManager *pIM= CInterfaceManager::getInstance();
CLuaState *lua= pIM->getLuaState(); CLuaState *lua= CLuaManager::getInstance().getLuaState();
nlassert(lua); nlassert(lua);
if(!_LUAEnvTableCreated) if(!_LUAEnvTableCreated)
@ -1782,7 +1784,7 @@ void CInterfaceGroup::deleteLUAEnvTable(bool recurse)
if(_LUAEnvTableCreated) if(_LUAEnvTableCreated)
{ {
CInterfaceManager *pIM= CInterfaceManager::getInstance(); CInterfaceManager *pIM= CInterfaceManager::getInstance();
CLuaState *lua= pIM->getLuaState(); CLuaState *lua= CLuaManager::getInstance().getLuaState();
nlassert(lua); nlassert(lua);
// replace simply the table with Nil, letting LUA Garbage collector do the realease stuff // replace simply the table with Nil, letting LUA Garbage collector do the realease stuff
@ -1866,7 +1868,7 @@ int CInterfaceGroup::luaFind(CLuaState &ls)
} }
else else
{ {
CLuaIHM::pushUIOnStack(ls, element); CLuaIHMRyzom::pushUIOnStack(ls, element);
} }
return 1; return 1;
} }
@ -1885,7 +1887,7 @@ CInterfaceElement* CInterfaceGroup::findFromShortId(const std::string &id)
int CInterfaceGroup::luaGetEnclosingContainer(CLuaState &ls) int CInterfaceGroup::luaGetEnclosingContainer(CLuaState &ls)
{ {
CLuaIHM::checkArgCount(ls, "CInterfaceGroup::getEnclosingContainer", 0); CLuaIHM::checkArgCount(ls, "CInterfaceGroup::getEnclosingContainer", 0);
CLuaIHM::pushUIOnStack(ls, getEnclosingContainer()); CLuaIHMRyzom::pushUIOnStack(ls, getEnclosingContainer());
return 1; return 1;
} }

View file

@ -5887,9 +5887,9 @@ void CInterfaceManager::getLuaValueInfo(std::string &str, sint index)
// If its a Userdata, try to display UI info // If its a Userdata, try to display UI info
else if(type==LUA_TUSERDATA) else if(type==LUA_TUSERDATA)
{ {
if(CLuaIHM::isUIOnStack(ls, index)) if(CLuaIHMRyzom::isUIOnStack(ls, index))
{ {
CInterfaceElement *ui= CLuaIHM::getUIOnStack(ls, index); CInterfaceElement *ui= CLuaIHMRyzom::getUIOnStack(ls, index);
str+= NLMISC::toString(" (ui=%p)", ui); str+= NLMISC::toString(" (ui=%p)", ui);
} }
} }

View file

@ -629,8 +629,6 @@ public:
// @{ // @{
/// Execute a lua script (smallScript for speed optimisation, see lua_helper). return false if parse/execute error (warning/sysinfo displayed) /// Execute a lua script (smallScript for speed optimisation, see lua_helper). return false if parse/execute error (warning/sysinfo displayed)
bool executeLuaScript(const std::string &luaScript, bool smallScript= false); bool executeLuaScript(const std::string &luaScript, bool smallScript= false);
/// Get the lua state (NULL if not inited)
class CLuaState *getLuaState() const {return _LuaState;}
/// Reload all LUA scripts inserted through <lua> /// Reload all LUA scripts inserted through <lua>
void reloadAllLuaFileScripts(); void reloadAllLuaFileScripts();
/// For debug: dump in the sysinfo and nlwarning state of lua. detail range from 0 to 2 (clamped). /// For debug: dump in the sysinfo and nlwarning state of lua. detail range from 0 to 2 (clamped).

View file

@ -110,6 +110,7 @@ using namespace NLGUI;
#include "lua_ihm.h" #include "lua_ihm.h"
#include "lua_ihm_ryzom.h" #include "lua_ihm_ryzom.h"
#include "../r2/editor.h" #include "../r2/editor.h"
#include "lua_manager.h"
#ifdef LUA_NEVRAX_VERSION #ifdef LUA_NEVRAX_VERSION
#include "lua_ide_dll_nevrax/include/lua_ide_dll/ide_interface.h" // external debugger #include "lua_ide_dll_nevrax/include/lua_ide_dll/ide_interface.h" // external debugger
@ -496,7 +497,7 @@ CInterfaceParser::~CInterfaceParser()
{ {
// delete _Pointer; // delete _Pointer;
_Pointer = NULL; _Pointer = NULL;
delete _LuaState; //delete _LuaState;
_LuaState = NULL; _LuaState = NULL;
} }
/** Convert a string into a memstream /** Convert a string into a memstream
@ -4663,7 +4664,9 @@ void CInterfaceParser::initLUA()
// create a new LUA environnement // create a new LUA environnement
nlassert(_LuaState==NULL); nlassert(_LuaState==NULL);
_LuaState= new CLuaState( ClientCfg.LoadLuaDebugger ); CLuaManager::enableLuaDebugging();
CLuaManager::getInstance();
_LuaState= CLuaManager::getInstance().getLuaState();
#ifdef LUA_NEVRAX_VERSION #ifdef LUA_NEVRAX_VERSION
extern ILuaIDEInterface *LuaDebuggerIDE; extern ILuaIDEInterface *LuaDebuggerIDE;
@ -4680,7 +4683,7 @@ void CInterfaceParser::uninitLUA()
{ {
// Delete all LUA environnement (and hence variables) // Delete all LUA environnement (and hence variables)
// delete _LuaState; // delete _LuaState;
_LuaState= NULL; // _LuaState= NULL;
// delete all .lua file loaded // delete all .lua file loaded
_LuaFileScripts.clear(); _LuaFileScripts.clear();

View file

@ -15,7 +15,6 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdpch.h"
#include "nel/gui/lua_helper.h" #include "nel/gui/lua_helper.h"
using namespace NLGUI; using namespace NLGUI;
@ -62,70 +61,14 @@ using namespace NLGUI;
#include "lua_ihm.h" #include "lua_ihm.h"
#include "reflect.h" #include "reflect.h"
#include "action_handler.h"
#include "action_handler_tools.h"
#include "interface_manager.h"
#include "interface_group.h"
#include "view_text.h"
#include "game_share/people_pd.h"
#include "group_tree.h"
#include "interface_link.h"
#include "interface_expr.h"
#include "people_interraction.h"
#include "nel/misc/algo.h" #include "nel/misc/algo.h"
#include "nel/misc/file.h" #include "nel/misc/file.h"
#include "nel/misc/i18n.h" #include "nel/misc/i18n.h"
#include "nel/misc/time_nl.h" #include "nel/misc/time_nl.h"
#include "skill_manager.h"
#include "group_html.h"
#include "../net_manager.h"
#include "../user_entity.h"
#include "sphrase_manager.h"
#include "guild_manager.h"
#include "../client_cfg.h"
#include "../sheet_manager.h"
#include "lua_object.h" #include "lua_object.h"
#include "game_share/emote_list_parser.h"
#include "game_share/pvp_clan.h"
#include "../weather.h"
#include "../continent_manager.h"
#include "../zone_util.h"
#include "../motion/user_controls.h"
#include "group_html_cs.h"
#include "bonus_malus.h"
#include "group_editbox.h"
#include "../entities.h"
#include "../sheet_manager.h" // for emotes
#include "../global.h" // for emotes
#include "../entity_animation_manager.h" // for emotes
#include "../net_manager.h" // for emotes
#include "../client_chat_manager.h" // for emotes
#include "../login.h"
#include "lua_object.h"
#include "../actions.h"
#include "../bg_downloader_access.h"
#include "../connection.h"
#include "../login_patch.h"
#include "bot_chat_page_all.h"
#include "bot_chat_page_ring_sessions.h"
#include "nel/georges/u_form_loader.h"
#include "nel/georges/u_form.h"
#include "nel/georges/u_form_elm.h"
#include "nel/misc/polygon.h" #include "nel/misc/polygon.h"
#include "game_share/scenario_entry_points.h" #include "lua_manager.h"
#include "game_share/bg_downloader_msg.h"
#include "game_share/constants.h"
#include "game_share/visual_slot_manager.h"
#ifdef LUA_NEVRAX_VERSION
#include "lua_ide_dll_nevrax/include/lua_ide_dll/ide_interface.h" // external debugger
#endif
#ifdef LUA_NEVRAX_VERSION
extern ILuaIDEInterface *LuaDebuggerIDE;
#endif
// *************************************************************************** // ***************************************************************************
/* /*
@ -136,15 +79,6 @@ Compilation is VERY SLOW
// *************************************************************************** // ***************************************************************************
using namespace NLMISC; using namespace NLMISC;
using namespace NLGEORGES;
using namespace R2;
extern NLMISC::CLog g_log;
extern CContinentManager ContinentMngr;
extern uint8 PlayerSelectedSlot;
extern CClientChatManager ChatMngr;
extern void addWebIGParams (string &url, bool trustedDomain);
// declare ostream << operator for ucstring -> registration of ucstring iin luabind will build a 'tostring' function from it // declare ostream << operator for ucstring -> registration of ucstring iin luabind will build a 'tostring' function from it
std::ostream &operator<<(std::ostream &str, const ucstring &value) std::ostream &operator<<(std::ostream &str, const ucstring &value)
@ -169,69 +103,6 @@ struct CMiscFunctions
}; };
/**
* Data structure pushed in lua (a userdata) to access CReflectableRefPtrTarget derived objects
* These includes element of the GUI.
* if holds a pointer to the reflectable object, and
* a cache to its CClassInfo for fast access to exported properties
* \see reflect.h
*/
//
class CReflectableLuaRef
{
public:
CReflectableLuaRef(CReflectableRefPtrTarget *ptr = NULL) : Ptr(ptr), _ClassInfo(NULL) {}
NLMISC::CRefPtr<CReflectableRefPtrTarget> Ptr;
const CClassInfo &getClassInfo() const;
// IMPORTANT : luaStringPtr should have been obtained from lua, see remark in CClassInfo
const CReflectedProperty *getProp(const char *luaStringPtr) const;
private:
// cache to class definition of the pointee object (once a CReflectableLuaRef created in lua, it remains a *const* pointer)
mutable const CClassInfo *_ClassInfo;
};
inline const CClassInfo &CReflectableLuaRef::getClassInfo() const
{
nlassert(Ptr); // class info should not be accessed for a null ptr
if (_ClassInfo) return *_ClassInfo;
_ClassInfo = Ptr->getClassInfo();
return *_ClassInfo;
}
const CReflectedProperty *CReflectableLuaRef::getProp(const char *luaStringPtr) const
{
const CClassInfo &ci = getClassInfo();
CClassInfo::TLuaStrToPropMap::const_iterator it = ci.LuaStrToProp.find(luaStringPtr);
if (it != ci.LuaStrToProp.end())
{
return it->second.Prop;
}
// slowly retrieve property, and store in cache
// NB nico : this could also be done at startup...
const CReflectedProperty *prop = CReflectSystem::getProperty(ci.ClassName, luaStringPtr, false);
if (!prop) return NULL;
CLuaIndexedProperty lip;
lip.Id = CLuaString(luaStringPtr); // keep a ref on the lua string to ensure that its pointer always remains valid
lip.Prop = prop;
ci.LuaStrToProp[luaStringPtr] = lip;
return prop;
}
// ***************************************************************************
static sint32 getTargetSlotNr()
{
const char *dbPath = "UI:VARIABLES:TARGET:SLOT";
CInterfaceManager *im = CInterfaceManager::getInstance();
CCDBNodeLeaf *node = im->getDbProp(dbPath, false);
if (!node) return 0;
if ((uint8) node->getValue32() == (uint8) CLFECOMMON::INVALID_SLOT)
{
return 0;
}
return node->getValue32();
}
// *************************************************************************** // ***************************************************************************
bool CLuaIHM::pop(CLuaState &ls, NLMISC::CRGBA &dest) bool CLuaIHM::pop(CLuaState &ls, NLMISC::CRGBA &dest)
{ {
@ -331,118 +202,6 @@ void CLuaIHM::push(CLuaState &ls, const ucstring &value)
#endif #endif
} }
// ***************************************************************************
// ***************************************************************************
// Special Action Handlers for Lua
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// Allow also to call script from expression
static DECLARE_INTERFACE_USER_FCT(lua)
{
if(args.size()!=1 || !args[0].toString())
{
nlwarning("<lua> requires 1 arg (string=script)");
return false;
}
// Retrieve lua state
CInterfaceManager *pIM= CInterfaceManager::getInstance();
CLuaState *state= pIM->getLuaState();
if(!state)
return false;
CLuaState &ls= *state;
// *** clear return value
const std::string retId= "__ui_internal_ret_";
CLuaStackChecker lsc(&ls);
ls.push(retId);
ls.pushNil();
ls.setTable(LUA_GLOBALSINDEX);
// *** execute script
std::string script= args[0].getString();
// assign return value in retId.
script= retId + "= " + script;
// execute a small script here, because most often exprs are called from xml files => lot of redundant script
pIM->executeLuaScript(script, true);
// *** retrieve and convert return value
ls.push(retId);
ls.getTable(LUA_GLOBALSINDEX);
bool ok= false;
sint type= ls.type();
if (type==LUA_TBOOLEAN)
{
// get and pop
bool val= ls.toBoolean();
ls.pop();
// set result
result.setBool(val);
ok= true;
}
else if(type==LUA_TNUMBER)
{
// get and pop
double val= ls.toNumber();
ls.pop();
// set double or integer?
if(val==floor(val))
result.setInteger(sint64(floor(val)));
else
result.setDouble(val);
ok= true;
}
else if(type==LUA_TSTRING)
{
// get and pop
std::string val;
ls.toString(-1, val);
ls.pop();
// set result
result.setString(val);
ok= true;
}
else if(type==LUA_TUSERDATA)
{
// NB: the value is poped in obj.set() (no need to do ls.pop());
// try with ucstring
ucstring ucstrVal;
if (CLuaIHM::pop(ls, ucstrVal))
{
result.setUCString(ucstrVal);
ok= true;
}
// try with RGBA
if(!ok)
{
NLMISC::CRGBA rgbaVal;
if (CLuaIHM::pop(ls, rgbaVal))
{
result.setRGBA(rgbaVal);
ok= true;
}
}
}
else
{
// error (nil for instance)
ls.pop();
}
return ok;
}
REGISTER_INTERFACE_USER_FCT("lua", lua)
// *************************************************************************** // ***************************************************************************
// *************************************************************************** // ***************************************************************************
// CInterface To LUA Registry // CInterface To LUA Registry
@ -452,8 +211,7 @@ REGISTER_INTERFACE_USER_FCT("lua", lua)
CLuaState * ELuaIHMException::getLuaState() CLuaState * ELuaIHMException::getLuaState()
{ {
CInterfaceManager *im = CInterfaceManager::getInstance(); return CLuaManager::getInstance().getLuaState();
return im->getLuaState();
} }
// *************************************************************************** // ***************************************************************************
@ -539,45 +297,9 @@ void CLuaIHM::registerBasics(CLuaState &ls)
.def_readwrite("y", &NLMISC::CVector2f::y) .def_readwrite("y", &NLMISC::CVector2f::y)
]; ];
// MISC ui ctors
struct CUICtor
{
// CGroupTree::SNode
static int SNode(CLuaState &ls)
{
CLuaIHM::checkArgCount(ls, "SNode", 0);
CLuaIHM::pushReflectableOnStack(ls, new CGroupTree::SNode);
return 1;
}
};
ls.registerFunc("SNode", CUICtor::SNode);
} }
// ***************************************************************************
CInterfaceElement *CLuaIHM::getUIRelative(CInterfaceElement *pIE, const std::string &propName)
{
//H_AUTO(Lua_CLuaIHM_getUIRelative)
if (pIE == NULL) return NULL;
// If the prop is "parent", then return the parent of the ui
if(propName=="parent")
{
return pIE->getParent();
}
// else try to get a child (if group/exist)
else
{
CInterfaceGroup *group= dynamic_cast<CInterfaceGroup*>(pIE);
if(group)
{
return group->getElement(group->getId()+":"+propName);
}
}
return NULL;
}
// *************************************************************************** // ***************************************************************************
int CLuaIHM::luaMethodCall(lua_State *ls) int CLuaIHM::luaMethodCall(lua_State *ls)
{ {
@ -688,71 +410,6 @@ void CLuaIHM::luaValueFromReflectedProperty(CLuaState &ls, CReflectable &reflect
static CLuaString lstr_Env("Env"); static CLuaString lstr_Env("Env");
static CLuaString lstr_isNil("isNil"); static CLuaString lstr_isNil("isNil");
// ***************************************************************************
int CLuaIHM::luaUIIndex(CLuaState &ls)
{
//H_AUTO(Lua_CLuaIHM_luaUIIndex)
nlassert(ls.getTop()==2);
// get the userdata and key
CReflectableLuaRef *pRefElm = (CReflectableLuaRef *) ls.toUserData(1);
const char *propName = ls.toString(2);
CReflectableRefPtrTarget *pRPT= (CReflectableRefPtrTarget*)(pRefElm->Ptr);
// ** try to get the Env Table (interface group only)
if(propName==lstr_isNil)
{
ls.push(pRPT==NULL);
return 1;
}
// Check the object is not NULL or freed
if(pRPT==NULL)
{
return 0;
}
// ** try to get the Env Table (interface group only)
if(propName==lstr_Env)
{
// Env can be bound to a CInterfaceGroup only
CInterfaceGroup *group= dynamic_cast<CInterfaceGroup*>(pRPT);
if(group==NULL)
{
ls.pushNil();
return 1;
}
else
{
group->pushLUAEnvTable();
return 1;
}
}
// ** try to get the property
const CReflectedProperty *prop = pRefElm->getProp(propName);
if (prop)
{
luaValueFromReflectedProperty(ls, *pRPT, *prop);
return 1;
}
// ** try to get a UI relative
CInterfaceElement *uiRelative= getUIRelative(dynamic_cast<CInterfaceElement *>(pRPT), propName);
if(uiRelative)
{
// push the UI onto the stack
CLuaIHM::pushUIOnStack(ls, uiRelative);
return 1;
}
// Fail to find any Attributes or elements
// Yoyo: don't write any message or warning because this may be a feature (if user want to test that something exit in the ui)
ls.pushNil();
return 1;
}
// *************************************************************************** // ***************************************************************************
void CLuaIHM::luaValueToReflectedProperty(CLuaState &ls, int stackIndex, CReflectable &target, const CReflectedProperty &property) throw(ELuaIHMException) void CLuaIHM::luaValueToReflectedProperty(CLuaState &ls, int stackIndex, CReflectable &target, const CReflectedProperty &property) throw(ELuaIHMException)
{ {
@ -832,312 +489,6 @@ void CLuaIHM::luaValueToReflectedProperty(CLuaState &ls, int stackIndex, CReflec
} }
// ***************************************************************************
int CLuaIHM::luaUINewIndex(CLuaState &ls)
{
//H_AUTO(Lua_CLuaIHM_luaUINewIndex)
nlassert(ls.getTop()==3);
// get the userdata and key
CReflectableLuaRef *pRefElm = (CReflectableLuaRef *) ls.toUserData(1);
nlassert(pRefElm);
CReflectableRefPtrTarget *pRPT= (CReflectableRefPtrTarget*)(pRefElm->Ptr);
// Check the UI is not NULL or freed
if(pRPT == NULL)
{
return 0;
}
const char *propName = ls.toString(2);
// ** try to set the Env Table (interface group only)
if(propName == lstr_Env)
{
CInterfaceElement *pIE = dynamic_cast<CInterfaceElement *>(pRPT);
std::string name ;
if (pIE)
{
name = pIE->getId();
}
else
{
name = "<reflectable element>";
}
// Exception!!! not allowed
throw ELuaIHMException("You cannot change the Env Table of '%s'", name.c_str());
}
// ** try to set the property
const CReflectedProperty *prop = pRefElm->getProp(propName);
if (prop)
{
luaValueToReflectedProperty(ls, 3, *pRPT, *prop);
return 0;
}
CInterfaceElement *pIE = dynamic_cast<CInterfaceElement *>(pRPT);
// ** try to get another UI (child or parent)
CInterfaceElement *uiRelative= getUIRelative(pIE, propName);
if(uiRelative)
{
// Exception!!! not allowed
throw ELuaIHMException("You cannot write into the UI '%s' of '%s'", propName, pIE->getId().c_str());
}
// ** Prop Not Found
throw ELuaIHMException("Property '%s' not found in '%s' of type %s", propName, pIE ? pIE->getId().c_str() : "<reflectable element>", typeid(*pRPT).name());
// Fail to find any Attributes or elements
return 0;
}
// ***************************************************************************
int CLuaIHM::luaUIEq(CLuaState &ls)
{
//H_AUTO(Lua_CLuaIHM_luaUIEq)
nlassert(ls.getTop() == 2);
// read lhs & rhs
// get the userdata and key
CReflectableLuaRef *lhs = (CReflectableLuaRef *) ls.toUserData(1);
CReflectableLuaRef *rhs = (CReflectableLuaRef *) ls.toUserData(2);
nlassert(lhs);
nlassert(rhs);
ls.push(lhs->Ptr == rhs->Ptr);
return 1;
}
// ***************************************************************************
int CLuaIHM::luaUIDtor(CLuaState &ls)
{
//H_AUTO(Lua_CLuaIHM_luaUIDtor)
nlassert(ls.getTop()==1);
// get the userdata
CReflectableLuaRef *pRefElm = (CReflectableLuaRef *) ls.toUserData(1);
nlassert(pRefElm);
// call dtor
pRefElm->~CReflectableLuaRef();
return 0;
}
// ***************************************************************************
int CLuaIHM::luaUINext(CLuaState &ls)
{
//H_AUTO(Lua_CLuaIHM_luaUINext)
// Code below allow enumeration of properties of a reflectable object
// From lua standpoint, the object is seen as a table with (key, value) pairs
// If object is a CInterfaceGroup, iteration is also done on sons (groups, controls & view).
if (ls.getTop() != 2)
{
CLuaIHM::fails(ls, "__next metamethod require 2 arguments (table & key)");
}
CLuaIHM::check(ls, isReflectableOnStack(ls, 1), "__next : require ui element as first arg");
CReflectableRefPtrTarget *reflectedObject = getReflectableOnStack(ls, 1);
// To traverse all properties / field of the object, we must be able to determine the next key from a previous key
// (keys are ordered)
// We use the 'TValueType' enum to know which kind of property we are traversing, and an index in this group of properties
// The key which uniquely identify an element / property in the reflectable object
struct CKey
{
enum TValueType
{
VTGroup = 0, // children groups (If the object is a CInterfaceGroup)
VTView, // children views (If the object is a CInterfaceView)
VTCtrl, // children controls (If the object is a CInterfaceCtrl)
VTProp // List of exported proeprties (For all relfectable objects)
};
TValueType ValueType;
sint Index;
const CClassInfo *ClassInfo; // if ValueType is "VTProp" -> give the class for which property are currently enumerated
//
static int tostring(CLuaState &ls) // '__print' metamathod
{
CLuaIHM::checkArgCount(ls, "reflected object metatable:__print", 1);
CKey key;
key.pop(ls);
switch(key.ValueType)
{
case VTGroup: ls.push(toString("_Group %d", key.Index)); break;
case VTView: ls.push(toString("_View %d", key.Index)); break;
case VTCtrl: ls.push(toString("_Ctrl %d", key.Index)); break;
case VTProp: ls.push(key.ClassInfo->Properties[key.Index].Name); break;
}
return 1;
}
// push the key on the lua stack
void push(CLuaState &ls)
{
void *ud = ls.newUserData(sizeof(*this));
*(CKey *) ud = *this;
getMetaTable(ls).push();
ls.setMetaTable(-2);
}
// pop the key from the lua stack
void pop(CLuaState &ls)
{
CLuaStackChecker lsc(&ls, -1);
if (!ls.isUserData(-1))
{
CLuaIHM::fails(ls, "Can't pop object, not a user data");
}
// check that metatable is good (it is share between all keys)
ls.getMetaTable(-1);
getMetaTable(ls).push();
if (!ls.rawEqual(-1, -2))
{
CLuaIHM::fails(ls, "Bad metatable for reflectable object key");
}
ls.pop(2);
// retrieve key
*this = *(CKey *) ls.toUserData(-1);
ls.pop();
}
// get the metatable for a CKey
CLuaObject &getMetaTable(CLuaState &ls)
{
static CLuaObject metatable;
if (!metatable.isValid())
{
// first build
CLuaStackChecker lsc(&ls);
ls.newTable();
ls.push("__tostring");
ls.push(CKey::tostring);
ls.setTable(-3);
metatable.pop(ls);
}
return metatable;
}
};
// Pop the current key to continue enumeration
CKey key;
if (ls.isNil(2))
{
// no key -> start of table
key.ValueType = CKey::VTGroup;
key.Index = -1;
}
else
{
key.pop(ls);
}
//
CInterfaceGroup *group = dynamic_cast<CInterfaceGroup *>(reflectedObject);
bool enumerate = true;
while (enumerate)
{
switch(key.ValueType)
{
case CKey::VTGroup:
if (!group || (key.Index + 1) == (sint) group->getGroups().size())
{
key.Index = -1;
key.ValueType = CKey::VTView; // continue enumeration with views
}
else
{
++ key.Index;
key.push(ls);
CLuaIHM::pushUIOnStack(ls, group->getGroups()[key.Index]);
return 2;
}
break;
case CKey::VTView:
if (!group || (key.Index + 1) == (sint) group->getViews().size())
{
key.Index = -1;
key.ValueType = CKey::VTCtrl; // continue enumeration with controls
}
else
{
++ key.Index;
key.push(ls);
CLuaIHM::pushUIOnStack(ls, group->getViews()[key.Index]);
return 2;
}
break;
case CKey::VTCtrl:
if (!group || (key.Index + 1) == (sint) group->getControls().size())
{
key.Index = -1;
key.ValueType = CKey::VTProp; // continue enumeration with properties
key.ClassInfo = reflectedObject->getClassInfo();
}
else
{
++ key.Index;
key.push(ls);
CLuaIHM::pushUIOnStack(ls, group->getControls()[key.Index]);
return 2;
}
break;
case CKey::VTProp:
if (!key.ClassInfo)
{
enumerate = false;
break;
}
if ((sint) key.ClassInfo->Properties.size() == (key.Index + 1))
{
key.ClassInfo = key.ClassInfo->ParentClass; // continue enumeration in parent class
key.Index = -1;
}
else
{
++ key.Index;
key.push(ls);
luaValueFromReflectedProperty(ls, *reflectedObject, key.ClassInfo->Properties[key.Index]);
return 2;
}
break;
default:
nlassert(0);
break;
}
}
ls.pushNil();
return 0;
}
// ***************************************************************************
int CLuaIHM::luaClientCfgIndex(CLuaState &ls)
{
//H_AUTO(Lua_CLuaIHM_luaClientCfgIndex)
CConfigFile::CVar *v = ClientCfg.ConfigFile.getVarPtr(ls.toString(2));
if (!v) return 0;
if (v->size() != 1)
{
// arrays not implemented (would require a second metatable)....
throw ELuaWrappedFunctionException(&ls, "Access to array inside client.cfg not supported.");
}
switch(v->Type)
{
case CConfigFile::CVar::T_REAL:
ls.push((double) v->asDouble());
return 1;
break;
case CConfigFile::CVar::T_STRING:
ls.push(v->asString());
return 1;
break;
default: // handle both T_INT && T_BOOL
case CConfigFile::CVar::T_INT:
ls.push((double) v->asInt());
return 1;
break;
}
return 0;
}
// ***************************************************************************
int CLuaIHM::luaClientCfgNewIndex(CLuaState &ls)
{
//H_AUTO(Lua_CLuaIHM_luaClientCfgNewIndex)
throw ELuaWrappedFunctionException(&ls, "Can't write into config file from lua.");
}
// *************************************************************************** // ***************************************************************************
void CLuaIHM::createLuaEnumTable(CLuaState &ls, const std::string &str) void CLuaIHM::createLuaEnumTable(CLuaState &ls, const std::string &str)
{ {
@ -1175,50 +526,6 @@ void CLuaIHM::registerIHM(CLuaState &ls)
//H_AUTO(Lua_CLuaIHM_registerIHM) //H_AUTO(Lua_CLuaIHM_registerIHM)
CLuaStackChecker lsc(&ls); CLuaStackChecker lsc(&ls);
// *** Register the metatable for access to client.cfg (nb nico this may be more general later -> access to any config file ...)
{
ls.pushValue(LUA_GLOBALSINDEX);
CLuaObject globals(ls);
CLuaObject clientCfg = globals.newTable("config");
CLuaObject mt = globals.newTable("__cfmt");
nlverify(clientCfg.setMetaTable(mt));
mt.setValue("__index", luaClientCfgIndex);
mt.setValue("__newindex", luaClientCfgNewIndex);
globals.setNil("__cfmt"); // remove temp metatable
}
// *** Register the MetaTable for UI userdata
ls.push(IHM_LUA_METATABLE); // "__ui_metatable"
ls.newTable(); // "__ui_metatable" {}
// set the '__index' method
ls.push("__index");
ls.push(luaUIIndex);
nlassert(ls.isCFunction());
ls.setTable(-3); // "__ui_metatable" {"__index"= CFunc_luaUIIndex}
// set the '__newindex' method
ls.push("__newindex");
ls.push(luaUINewIndex);
nlassert(ls.isCFunction());
ls.setTable(-3);
// set the '__newindex' method
ls.push("__gc");
ls.push(luaUIDtor);
nlassert(ls.isCFunction());
ls.setTable(-3);
// set the '__eq' method
ls.push("__eq");
ls.push(luaUIEq);
nlassert(ls.isCFunction());
ls.setTable(-3);
// set the custom '__next' method
ls.push("__next");
ls.push(luaUINext);
nlassert(ls.isCFunction());
ls.setTable(-3);
// set registry
ls.setTable(LUA_REGISTRYINDEX);
// *** Register a Table for ui env. // *** Register a Table for ui env.
ls.push(IHM_LUA_ENVTABLE); // "__ui_envtable" ls.push(IHM_LUA_ENVTABLE); // "__ui_envtable"
ls.newTable(); // "__ui_envtable" {} ls.newTable(); // "__ui_envtable" {}
@ -1392,28 +699,6 @@ CReflectableRefPtrTarget *CLuaIHM::getReflectableOnStack(CLuaState &ls, sint
} }
// ***************************************************************************
void CLuaIHM::pushUIOnStack(CLuaState &ls, class CInterfaceElement *pIE)
{
//H_AUTO(Lua_CLuaIHM_pushUIOnStack)
pushReflectableOnStack(ls, pIE);
}
// ***************************************************************************
bool CLuaIHM::isUIOnStack(CLuaState &ls, sint index)
{
//H_AUTO(Lua_CLuaIHM_isUIOnStack)
return getUIOnStack(ls, index) != NULL;
}
// ***************************************************************************
CInterfaceElement *CLuaIHM::getUIOnStack(CLuaState &ls, sint index)
{
//H_AUTO(Lua_CLuaIHM_getUIOnStack)
return dynamic_cast<CInterfaceElement *>(getReflectableOnStack(ls, index));
}
// *************************************************************************** // ***************************************************************************
// *************************************************************************** // ***************************************************************************
// LUA IHM Functions // LUA IHM Functions
@ -1429,26 +714,6 @@ uint32 CLuaIHM::getLocalTime()
} }
// ***************************************************************************
static CEntityCL *getTargetEntity()
{
const char *dbPath = "UI:VARIABLES:TARGET:SLOT";
CInterfaceManager *im = CInterfaceManager::getInstance();
CCDBNodeLeaf *node = im->getDbProp(dbPath, false);
if (!node) return NULL;
if ((uint8) node->getValue32() == (uint8) CLFECOMMON::INVALID_SLOT)
{
return NULL;
}
return EntitiesMngr.entity((uint) node->getValue32());
}
// ***************************************************************************
static CEntityCL *getSlotEntity(uint slot)
{
return EntitiesMngr.entity(slot);
}
// *************************************************************************** // ***************************************************************************
std::string CLuaIHM::findReplaceAll(const std::string &str, const std::string &search, const std::string &replace) std::string CLuaIHM::findReplaceAll(const std::string &str, const std::string &search, const std::string &replace)
{ {
@ -1489,78 +754,6 @@ ucstring CLuaIHM::findReplaceAll(const ucstring &str, const ucstring &search,
} }
// ***************************************************************************
int CLuaIHM::runExprAndPushResult(CLuaState &ls, const std::string &expr)
{
//H_AUTO(Lua_CLuaIHM_runExprAndPushResult)
// Execute expression
CInterfaceExprValue value;
if (CInterfaceExpr::eval(expr, value, NULL))
{
switch(value.getType())
{
case CInterfaceExprValue::Boolean:
ls.push(value.getBool());
break;
case CInterfaceExprValue::Integer:
ls.push((double)value.getInteger());
break;
case CInterfaceExprValue::Double:
ls.push(value.getDouble());
break;
case CInterfaceExprValue::String:
{
ucstring ucstr= value.getUCString();
// Yoyo: dynamically decide whether must return a string or a ucstring
bool mustUseUCString= false;
for (uint i = 0; i < ucstr.size (); i++)
{
if (ucstr[i] > 255)
{
mustUseUCString= true;
break;
}
}
// push a ucstring?
if(mustUseUCString)
{
#if LUABIND_VERSION > 600
luabind::detail::push(ls.getStatePointer(), ucstr);
#else
luabind::object obj(ls.getStatePointer(), ucstr);
obj.pushvalue();
#endif
}
else
{
ls.push(ucstr.toString());
}
break;
}
case CInterfaceExprValue::RGBA:
{
CRGBA color = value.getRGBA();
#if LUABIND_VERSION > 600
luabind::detail::push(ls.getStatePointer(), color);
#else
luabind::object obj(ls.getStatePointer(), color);
obj.pushvalue();
#endif
break;
}
break;
case CInterfaceExprValue::UserType: // Yoyo: don't care UserType...
default:
ls.pushNil();
break;
}
}
else
ls.pushNil();
return 1;
}
// *************************************************************************** // ***************************************************************************
void CLuaIHM::fails(CLuaState &ls, const char *format, ...) void CLuaIHM::fails(CLuaState &ls, const char *format, ...)
{ {
@ -1646,21 +839,6 @@ void CLuaIHM::checkArgTypeRGBA(CLuaState &ls, const char *funcName, uint index)
} }
} }
// ***************************************************************************
void CLuaIHM::checkArgTypeUIElement(CLuaState &ls, const char *funcName, uint index)
{
//H_AUTO(Lua_CLuaIHM_checkArgTypeUIElement)
nlassert(index > 0);
if (ls.getTop() < (int) index)
{
fails(ls, "%s : argument %d of expected type ui element was not defined", funcName, index);
}
if (!isUIOnStack(ls, index))
{
fails(ls, "%s : argument %d of expected type ui element has bad type : %s", funcName, index, ls.getTypename(ls.type(index)), ls.type(index));
}
}
// *************************************************************************** // ***************************************************************************
void CLuaIHM::checkArgTypeUCString(CLuaState &ls, const char *funcName, uint index) void CLuaIHM::checkArgTypeUCString(CLuaState &ls, const char *funcName, uint index)
{ {

View file

@ -74,11 +74,6 @@ class CLuaIHM
public: public:
static void registerAll(CLuaState &ls); static void registerAll(CLuaState &ls);
// CInterfaceElement management on stack, stored by a CRefPtr.
static void pushUIOnStack(CLuaState &ls, class CInterfaceElement *pIE);
static bool isUIOnStack(CLuaState &ls, sint index);
static CInterfaceElement *getUIOnStack(CLuaState &ls, sint index);
/** CReflectableInterfaceElement management on stack, stored by a CRefPtr. /** CReflectableInterfaceElement management on stack, stored by a CRefPtr.
* May be called as well for ui element, because they derive from CReflectableRefPtrTarget * May be called as well for ui element, because they derive from CReflectableRefPtrTarget
*/ */
@ -110,7 +105,6 @@ public:
static void check(CLuaState &ls, bool ok, const std::string &failReason); static void check(CLuaState &ls, bool ok, const std::string &failReason);
static void checkArgType(CLuaState &ls, const char *funcName, uint index, int argType); static void checkArgType(CLuaState &ls, const char *funcName, uint index, int argType);
static void checkArgTypeRGBA(CLuaState &ls, const char *funcName, uint index); static void checkArgTypeRGBA(CLuaState &ls, const char *funcName, uint index);
static void checkArgTypeUIElement(CLuaState &ls, const char *funcName, uint index);
static void checkArgTypeUCString(CLuaState &ls, const char *funcName, uint index); static void checkArgTypeUCString(CLuaState &ls, const char *funcName, uint index);
/** throw a lua expection (inside a C function called from lua) with the given reason, and the current call stack /** throw a lua expection (inside a C function called from lua) with the given reason, and the current call stack
* The various check... function call this function when their test fails * The various check... function call this function when their test fails
@ -140,16 +134,6 @@ private:
static void registerIHM(CLuaState &ls); static void registerIHM(CLuaState &ls);
static void createLuaEnumTable(CLuaState &ls, const std::string &str); static void createLuaEnumTable(CLuaState &ls, const std::string &str);
// Functions for the ui metatable
static class CInterfaceElement *getUIRelative(class CInterfaceElement *pIE, const std::string &propName);
static int luaUIIndex(CLuaState &ls);
static int luaUINewIndex(CLuaState &ls);
static int luaUIEq(CLuaState &ls);
static int luaUINext(CLuaState &ls);
static int luaUIDtor(CLuaState &ls);
static int luaClientCfgIndex(CLuaState &ls);
static int luaClientCfgNewIndex(CLuaState &ls);
/// \name Exported Functions /// \name Exported Functions
// @{ // @{
@ -169,9 +153,6 @@ private:
// Function export tools // Function export tools
// Function to forward lua call to C++ to a 'lua method' exported from a reflected object // Function to forward lua call to C++ to a 'lua method' exported from a reflected object
static int luaMethodCall(lua_State *ls); static int luaMethodCall(lua_State *ls);
public:
static int runExprAndPushResult(CLuaState &ls, const std::string &expr); // Used by runExpr and runFct
}; };

View file

@ -100,6 +100,7 @@
#include "game_share/bg_downloader_msg.h" #include "game_share/bg_downloader_msg.h"
#include "game_share/constants.h" #include "game_share/constants.h"
#include "game_share/visual_slot_manager.h" #include "game_share/visual_slot_manager.h"
#include "lua_manager.h"
#ifdef LUA_NEVRAX_VERSION #ifdef LUA_NEVRAX_VERSION
#include "lua_ide_dll_nevrax/include/lua_ide_dll/ide_interface.h" // external debugger #include "lua_ide_dll_nevrax/include/lua_ide_dll/ide_interface.h" // external debugger
@ -148,6 +149,109 @@ private:
REGISTER_ACTION_HANDLER( CHandlerLUA, "lua"); REGISTER_ACTION_HANDLER( CHandlerLUA, "lua");
std::deque<CRefPtr<CCtrlBase> > CHandlerLUA::_UICallerStack; std::deque<CRefPtr<CCtrlBase> > CHandlerLUA::_UICallerStack;
// ***************************************************************************
// Allow also to call script from expression
static DECLARE_INTERFACE_USER_FCT(lua)
{
if(args.size()!=1 || !args[0].toString())
{
nlwarning("<lua> requires 1 arg (string=script)");
return false;
}
// Retrieve lua state
CInterfaceManager *pIM= CInterfaceManager::getInstance();
CLuaState *state= CLuaManager::getInstance().getLuaState();
if(!state)
return false;
CLuaState &ls= *state;
// *** clear return value
const std::string retId= "__ui_internal_ret_";
CLuaStackChecker lsc(&ls);
ls.push(retId);
ls.pushNil();
ls.setTable(LUA_GLOBALSINDEX);
// *** execute script
std::string script= args[0].getString();
// assign return value in retId.
script= retId + "= " + script;
// execute a small script here, because most often exprs are called from xml files => lot of redundant script
pIM->executeLuaScript(script, true);
// *** retrieve and convert return value
ls.push(retId);
ls.getTable(LUA_GLOBALSINDEX);
bool ok= false;
sint type= ls.type();
if (type==LUA_TBOOLEAN)
{
// get and pop
bool val= ls.toBoolean();
ls.pop();
// set result
result.setBool(val);
ok= true;
}
else if(type==LUA_TNUMBER)
{
// get and pop
double val= ls.toNumber();
ls.pop();
// set double or integer?
if(val==floor(val))
result.setInteger(sint64(floor(val)));
else
result.setDouble(val);
ok= true;
}
else if(type==LUA_TSTRING)
{
// get and pop
std::string val;
ls.toString(-1, val);
ls.pop();
// set result
result.setString(val);
ok= true;
}
else if(type==LUA_TUSERDATA)
{
// NB: the value is poped in obj.set() (no need to do ls.pop());
// try with ucstring
ucstring ucstrVal;
if (CLuaIHM::pop(ls, ucstrVal))
{
result.setUCString(ucstrVal);
ok= true;
}
// try with RGBA
if(!ok)
{
NLMISC::CRGBA rgbaVal;
if (CLuaIHM::pop(ls, rgbaVal))
{
result.setRGBA(rgbaVal);
ok= true;
}
}
}
else
{
// error (nil for instance)
ls.pop();
}
return ok;
}
REGISTER_INTERFACE_USER_FCT("lua", lua)
CCtrlBase *CHandlerLUA::getUICaller() CCtrlBase *CHandlerLUA::getUICaller()
{ {
if(_UICallerStack.empty()) if(_UICallerStack.empty())
@ -169,6 +273,440 @@ CCtrlBase *CHandlerLUA::getUICaller()
#define LUABIND_FUNC(__func__) luabind::def(#__func__, &__func__) #define LUABIND_FUNC(__func__) luabind::def(#__func__, &__func__)
// ***************************************************************************
int CLuaIHMRyzom::luaClientCfgIndex(CLuaState &ls)
{
//H_AUTO(Lua_CLuaIHM_luaClientCfgIndex)
CConfigFile::CVar *v = ClientCfg.ConfigFile.getVarPtr(ls.toString(2));
if (!v) return 0;
if (v->size() != 1)
{
// arrays not implemented (would require a second metatable)....
throw ELuaWrappedFunctionException(&ls, "Access to array inside client.cfg not supported.");
}
switch(v->Type)
{
case CConfigFile::CVar::T_REAL:
ls.push((double) v->asDouble());
return 1;
break;
case CConfigFile::CVar::T_STRING:
ls.push(v->asString());
return 1;
break;
default: // handle both T_INT && T_BOOL
case CConfigFile::CVar::T_INT:
ls.push((double) v->asInt());
return 1;
break;
}
return 0;
}
// ***************************************************************************
int CLuaIHMRyzom::luaClientCfgNewIndex(CLuaState &ls)
{
//H_AUTO(Lua_CLuaIHM_luaClientCfgNewIndex)
throw ELuaWrappedFunctionException(&ls, "Can't write into config file from lua.");
}
// ***************************************************************************
CInterfaceElement *CLuaIHMRyzom::getUIRelative(CInterfaceElement *pIE, const std::string &propName)
{
//H_AUTO(Lua_CLuaIHM_getUIRelative)
if (pIE == NULL) return NULL;
// If the prop is "parent", then return the parent of the ui
if(propName=="parent")
{
return pIE->getParent();
}
// else try to get a child (if group/exist)
else
{
CInterfaceGroup *group= dynamic_cast<CInterfaceGroup*>(pIE);
if(group)
{
return group->getElement(group->getId()+":"+propName);
}
}
return NULL;
}
static CLuaString lstr_Env("Env");
static CLuaString lstr_isNil("isNil");
// ***************************************************************************
int CLuaIHMRyzom::luaUIIndex(CLuaState &ls)
{
//H_AUTO(Lua_CLuaIHM_luaUIIndex)
nlassert(ls.getTop()==2);
// get the userdata and key
CReflectableLuaRef *pRefElm = (CReflectableLuaRef *) ls.toUserData(1);
const char *propName = ls.toString(2);
CReflectableRefPtrTarget *pRPT= (CReflectableRefPtrTarget*)(pRefElm->Ptr);
// ** try to get the Env Table (interface group only)
if(propName==lstr_isNil)
{
ls.push(pRPT==NULL);
return 1;
}
// Check the object is not NULL or freed
if(pRPT==NULL)
{
return 0;
}
// ** try to get the Env Table (interface group only)
if(propName==lstr_Env)
{
// Env can be bound to a CInterfaceGroup only
CInterfaceGroup *group= dynamic_cast<CInterfaceGroup*>(pRPT);
if(group==NULL)
{
ls.pushNil();
return 1;
}
else
{
group->pushLUAEnvTable();
return 1;
}
}
// ** try to get the property
const CReflectedProperty *prop = pRefElm->getProp(propName);
if (prop)
{
CLuaIHM::luaValueFromReflectedProperty(ls, *pRPT, *prop);
return 1;
}
// ** try to get a UI relative
CInterfaceElement *uiRelative= getUIRelative(dynamic_cast<CInterfaceElement *>(pRPT), propName);
if(uiRelative)
{
// push the UI onto the stack
pushUIOnStack(ls, uiRelative);
return 1;
}
// Fail to find any Attributes or elements
// Yoyo: don't write any message or warning because this may be a feature (if user want to test that something exit in the ui)
ls.pushNil();
return 1;
}
// ***************************************************************************
int CLuaIHMRyzom::luaUINewIndex(CLuaState &ls)
{
//H_AUTO(Lua_CLuaIHM_luaUINewIndex)
nlassert(ls.getTop()==3);
// get the userdata and key
CReflectableLuaRef *pRefElm = (CReflectableLuaRef *) ls.toUserData(1);
nlassert(pRefElm);
CReflectableRefPtrTarget *pRPT= (CReflectableRefPtrTarget*)(pRefElm->Ptr);
// Check the UI is not NULL or freed
if(pRPT == NULL)
{
return 0;
}
const char *propName = ls.toString(2);
// ** try to set the Env Table (interface group only)
if(propName == lstr_Env)
{
CInterfaceElement *pIE = dynamic_cast<CInterfaceElement *>(pRPT);
std::string name ;
if (pIE)
{
name = pIE->getId();
}
else
{
name = "<reflectable element>";
}
// Exception!!! not allowed
throw ELuaIHMException("You cannot change the Env Table of '%s'", name.c_str());
}
// ** try to set the property
const CReflectedProperty *prop = pRefElm->getProp(propName);
if (prop)
{
CLuaIHM::luaValueToReflectedProperty(ls, 3, *pRPT, *prop);
return 0;
}
CInterfaceElement *pIE = dynamic_cast<CInterfaceElement *>(pRPT);
// ** try to get another UI (child or parent)
CInterfaceElement *uiRelative= getUIRelative(pIE, propName);
if(uiRelative)
{
// Exception!!! not allowed
throw ELuaIHMException("You cannot write into the UI '%s' of '%s'", propName, pIE->getId().c_str());
}
// ** Prop Not Found
throw ELuaIHMException("Property '%s' not found in '%s' of type %s", propName, pIE ? pIE->getId().c_str() : "<reflectable element>", typeid(*pRPT).name());
// Fail to find any Attributes or elements
return 0;
}
// ***************************************************************************
int CLuaIHMRyzom::luaUIEq(CLuaState &ls)
{
//H_AUTO(Lua_CLuaIHM_luaUIEq)
nlassert(ls.getTop() == 2);
// read lhs & rhs
// get the userdata and key
CReflectableLuaRef *lhs = (CReflectableLuaRef *) ls.toUserData(1);
CReflectableLuaRef *rhs = (CReflectableLuaRef *) ls.toUserData(2);
nlassert(lhs);
nlassert(rhs);
ls.push(lhs->Ptr == rhs->Ptr);
return 1;
}
// ***************************************************************************
int CLuaIHMRyzom::luaUIDtor(CLuaState &ls)
{
//H_AUTO(Lua_CLuaIHM_luaUIDtor)
nlassert(ls.getTop()==1);
// get the userdata
CReflectableLuaRef *pRefElm = (CReflectableLuaRef *) ls.toUserData(1);
nlassert(pRefElm);
// call dtor
pRefElm->~CReflectableLuaRef();
return 0;
}
// ***************************************************************************
int CLuaIHMRyzom::luaUINext(CLuaState &ls)
{
//H_AUTO(Lua_CLuaIHM_luaUINext)
// Code below allow enumeration of properties of a reflectable object
// From lua standpoint, the object is seen as a table with (key, value) pairs
// If object is a CInterfaceGroup, iteration is also done on sons (groups, controls & view).
if (ls.getTop() != 2)
{
CLuaIHM::fails(ls, "__next metamethod require 2 arguments (table & key)");
}
CLuaIHM::check(ls, CLuaIHM::isReflectableOnStack(ls, 1), "__next : require ui element as first arg");
CReflectableRefPtrTarget *reflectedObject = CLuaIHM::getReflectableOnStack(ls, 1);
// To traverse all properties / field of the object, we must be able to determine the next key from a previous key
// (keys are ordered)
// We use the 'TValueType' enum to know which kind of property we are traversing, and an index in this group of properties
// The key which uniquely identify an element / property in the reflectable object
struct CKey
{
enum TValueType
{
VTGroup = 0, // children groups (If the object is a CInterfaceGroup)
VTView, // children views (If the object is a CInterfaceView)
VTCtrl, // children controls (If the object is a CInterfaceCtrl)
VTProp // List of exported proeprties (For all relfectable objects)
};
TValueType ValueType;
sint Index;
const CClassInfo *ClassInfo; // if ValueType is "VTProp" -> give the class for which property are currently enumerated
//
static int tostring(CLuaState &ls) // '__print' metamathod
{
CLuaIHM::checkArgCount(ls, "reflected object metatable:__print", 1);
CKey key;
key.pop(ls);
switch(key.ValueType)
{
case VTGroup: ls.push(toString("_Group %d", key.Index)); break;
case VTView: ls.push(toString("_View %d", key.Index)); break;
case VTCtrl: ls.push(toString("_Ctrl %d", key.Index)); break;
case VTProp: ls.push(key.ClassInfo->Properties[key.Index].Name); break;
}
return 1;
}
// push the key on the lua stack
void push(CLuaState &ls)
{
void *ud = ls.newUserData(sizeof(*this));
*(CKey *) ud = *this;
getMetaTable(ls).push();
ls.setMetaTable(-2);
}
// pop the key from the lua stack
void pop(CLuaState &ls)
{
CLuaStackChecker lsc(&ls, -1);
if (!ls.isUserData(-1))
{
CLuaIHM::fails(ls, "Can't pop object, not a user data");
}
// check that metatable is good (it is share between all keys)
ls.getMetaTable(-1);
getMetaTable(ls).push();
if (!ls.rawEqual(-1, -2))
{
CLuaIHM::fails(ls, "Bad metatable for reflectable object key");
}
ls.pop(2);
// retrieve key
*this = *(CKey *) ls.toUserData(-1);
ls.pop();
}
// get the metatable for a CKey
CLuaObject &getMetaTable(CLuaState &ls)
{
static CLuaObject metatable;
if (!metatable.isValid())
{
// first build
CLuaStackChecker lsc(&ls);
ls.newTable();
ls.push("__tostring");
ls.push(CKey::tostring);
ls.setTable(-3);
metatable.pop(ls);
}
return metatable;
}
};
// Pop the current key to continue enumeration
CKey key;
if (ls.isNil(2))
{
// no key -> start of table
key.ValueType = CKey::VTGroup;
key.Index = -1;
}
else
{
key.pop(ls);
}
//
CInterfaceGroup *group = dynamic_cast<CInterfaceGroup *>(reflectedObject);
bool enumerate = true;
while (enumerate)
{
switch(key.ValueType)
{
case CKey::VTGroup:
if (!group || (key.Index + 1) == (sint) group->getGroups().size())
{
key.Index = -1;
key.ValueType = CKey::VTView; // continue enumeration with views
}
else
{
++ key.Index;
key.push(ls);
pushUIOnStack(ls, group->getGroups()[key.Index]);
return 2;
}
break;
case CKey::VTView:
if (!group || (key.Index + 1) == (sint) group->getViews().size())
{
key.Index = -1;
key.ValueType = CKey::VTCtrl; // continue enumeration with controls
}
else
{
++ key.Index;
key.push(ls);
pushUIOnStack(ls, group->getViews()[key.Index]);
return 2;
}
break;
case CKey::VTCtrl:
if (!group || (key.Index + 1) == (sint) group->getControls().size())
{
key.Index = -1;
key.ValueType = CKey::VTProp; // continue enumeration with properties
key.ClassInfo = reflectedObject->getClassInfo();
}
else
{
++ key.Index;
key.push(ls);
pushUIOnStack(ls, group->getControls()[key.Index]);
return 2;
}
break;
case CKey::VTProp:
if (!key.ClassInfo)
{
enumerate = false;
break;
}
if ((sint) key.ClassInfo->Properties.size() == (key.Index + 1))
{
key.ClassInfo = key.ClassInfo->ParentClass; // continue enumeration in parent class
key.Index = -1;
}
else
{
++ key.Index;
key.push(ls);
CLuaIHM::luaValueFromReflectedProperty(ls, *reflectedObject, key.ClassInfo->Properties[key.Index]);
return 2;
}
break;
default:
nlassert(0);
break;
}
}
ls.pushNil();
return 0;
}
// ***************************************************************************
void CLuaIHMRyzom::pushUIOnStack(CLuaState &ls, class CInterfaceElement *pIE)
{
//H_AUTO(Lua_CLuaIHM_pushUIOnStack)
CLuaIHM::pushReflectableOnStack(ls, pIE);
}
// ***************************************************************************
bool CLuaIHMRyzom::isUIOnStack(CLuaState &ls, sint index)
{
//H_AUTO(Lua_CLuaIHM_isUIOnStack)
return getUIOnStack(ls, index) != NULL;
}
// ***************************************************************************
CInterfaceElement *CLuaIHMRyzom::getUIOnStack(CLuaState &ls, sint index)
{
//H_AUTO(Lua_CLuaIHM_getUIOnStack)
return dynamic_cast<CInterfaceElement *>(CLuaIHM::getReflectableOnStack(ls, index));
}
// ***************************************************************************
void CLuaIHMRyzom::checkArgTypeUIElement(CLuaState &ls, const char *funcName, uint index)
{
//H_AUTO(Lua_CLuaIHM_checkArgTypeUIElement)
nlassert(index > 0);
if (ls.getTop() < (int) index)
{
CLuaIHM::fails(ls, "%s : argument %d of expected type ui element was not defined", funcName, index);
}
if (!isUIOnStack(ls, index))
{
CLuaIHM::fails(ls, "%s : argument %d of expected type ui element has bad type : %s", funcName, index, ls.getTypename(ls.type(index)), ls.type(index));
}
}
// *************************************************************************** // ***************************************************************************
void CLuaIHMRyzom::createLuaEnumTable(CLuaState &ls, const std::string &str) void CLuaIHMRyzom::createLuaEnumTable(CLuaState &ls, const std::string &str)
{ {
@ -193,6 +731,62 @@ void CLuaIHMRyzom::RegisterRyzomFunctions( NLGUI::CLuaState &ls )
{ {
CLuaStackChecker lsc( &ls ); CLuaStackChecker lsc( &ls );
// MISC ui ctors
struct CUICtor
{
// CGroupTree::SNode
static int SNode(CLuaState &ls)
{
CLuaIHM::checkArgCount(ls, "SNode", 0);
CLuaIHM::pushReflectableOnStack(ls, new CGroupTree::SNode);
return 1;
}
};
ls.registerFunc("SNode", CUICtor::SNode);
// *** Register the metatable for access to client.cfg (nb nico this may be more general later -> access to any config file ...)
ls.pushValue(LUA_GLOBALSINDEX);
CLuaObject globals(ls);
CLuaObject clientCfg = globals.newTable("config");
CLuaObject mt = globals.newTable("__cfmt");
nlverify(clientCfg.setMetaTable(mt));
mt.setValue("__index", luaClientCfgIndex);
mt.setValue("__newindex", luaClientCfgNewIndex);
globals.setNil("__cfmt"); // remove temp metatable
// *** Register the MetaTable for UI userdata
ls.push(IHM_LUA_METATABLE); // "__ui_metatable"
ls.newTable(); // "__ui_metatable" {}
// set the '__index' method
ls.push("__index");
ls.push(luaUIIndex);
nlassert(ls.isCFunction());
ls.setTable(-3); // "__ui_metatable" {"__index"= CFunc_luaUIIndex}
// set the '__newindex' method
ls.push("__newindex");
ls.push(luaUINewIndex);
nlassert(ls.isCFunction());
ls.setTable(-3);
// set the '__newindex' method
ls.push("__gc");
ls.push(luaUIDtor);
nlassert(ls.isCFunction());
ls.setTable(-3);
// set the '__eq' method
ls.push("__eq");
ls.push(luaUIEq);
nlassert(ls.isCFunction());
ls.setTable(-3);
// set the custom '__next' method
ls.push("__next");
ls.push(luaUINext);
nlassert(ls.isCFunction());
ls.setTable(-3);
// set registry
ls.setTable(LUA_REGISTRYINDEX);
ls.registerFunc( "getUI", getUI ); ls.registerFunc( "getUI", getUI );
ls.registerFunc("setOnDraw", setOnDraw); ls.registerFunc("setOnDraw", setOnDraw);
ls.registerFunc("setCaptureKeyboard", setCaptureKeyboard); ls.registerFunc("setCaptureKeyboard", setCaptureKeyboard);
@ -438,7 +1032,7 @@ int CLuaIHMRyzom::getUI(CLuaState &ls)
} }
else else
{ {
CLuaIHM::pushUIOnStack(ls, pIE); pushUIOnStack(ls, pIE);
} }
return 1; return 1;
} }
@ -449,8 +1043,8 @@ int CLuaIHMRyzom::setCaptureKeyboard(CLuaState &ls)
//H_AUTO(Lua_CLuaIHM_setCaptureKeyboard) //H_AUTO(Lua_CLuaIHM_setCaptureKeyboard)
const char *funcName = "setCaptureKeyboard"; const char *funcName = "setCaptureKeyboard";
CLuaIHM::checkArgCount(ls, funcName, 1); CLuaIHM::checkArgCount(ls, funcName, 1);
CLuaIHM::checkArgTypeUIElement(ls, funcName, 1); checkArgTypeUIElement(ls, funcName, 1);
CCtrlBase *ctrl = dynamic_cast<CCtrlBase *>( CLuaIHM::getUIOnStack(ls, 1)); CCtrlBase *ctrl = dynamic_cast<CCtrlBase *>( getUIOnStack(ls, 1));
if (!ctrl) if (!ctrl)
{ {
CLuaIHM::fails(ls, "%s waits a ui control as arg 1", funcName); CLuaIHM::fails(ls, "%s waits a ui control as arg 1", funcName);
@ -480,11 +1074,11 @@ int CLuaIHMRyzom::setOnDraw(CLuaState &ls)
// params: CInterfaceGroup*, "script". // params: CInterfaceGroup*, "script".
// return: none // return: none
CLuaIHM::checkArgCount(ls, "setOnDraw", 2); CLuaIHM::checkArgCount(ls, "setOnDraw", 2);
CLuaIHM::check(ls, CLuaIHM::isUIOnStack(ls, 1), "setOnDraw() requires a UI object in param 1"); CLuaIHM::check(ls, isUIOnStack(ls, 1), "setOnDraw() requires a UI object in param 1");
CLuaIHM::check(ls, ls.isString(2), "setOnDraw() requires a string in param 2"); CLuaIHM::check(ls, ls.isString(2), "setOnDraw() requires a string in param 2");
// retrieve args // retrieve args
CInterfaceElement *pIE= CLuaIHM::getUIOnStack(ls, 1); CInterfaceElement *pIE= getUIOnStack(ls, 1);
std::string script; std::string script;
ls.toString(2, script); ls.toString(2, script);
@ -507,12 +1101,12 @@ int CLuaIHMRyzom::addOnDbChange(CLuaState &ls)
// params: CInterfaceGroup*, "dblist", "script". // params: CInterfaceGroup*, "dblist", "script".
// return: none // return: none
CLuaIHM::checkArgCount(ls, "addOnDbChange", 3); CLuaIHM::checkArgCount(ls, "addOnDbChange", 3);
CLuaIHM::check(ls, CLuaIHM::isUIOnStack(ls, 1), "addOnDbChange() requires a UI object in param 1"); CLuaIHM::check(ls, isUIOnStack(ls, 1), "addOnDbChange() requires a UI object in param 1");
CLuaIHM::check(ls, ls.isString(2), "addOnDbChange() requires a string in param 2"); CLuaIHM::check(ls, ls.isString(2), "addOnDbChange() requires a string in param 2");
CLuaIHM::check(ls, ls.isString(3), "addOnDbChange() requires a string in param 3"); CLuaIHM::check(ls, ls.isString(3), "addOnDbChange() requires a string in param 3");
// retrieve args // retrieve args
CInterfaceElement *pIE= CLuaIHM::getUIOnStack(ls, 1); CInterfaceElement *pIE= getUIOnStack(ls, 1);
std::string dbList, script; std::string dbList, script;
ls.toString(2, dbList); ls.toString(2, dbList);
ls.toString(3, script); ls.toString(3, script);
@ -537,11 +1131,11 @@ int CLuaIHMRyzom::removeOnDbChange(CLuaState &ls)
// params: CInterfaceGroup*, "dbList" // params: CInterfaceGroup*, "dbList"
// return: none // return: none
CLuaIHM::checkArgCount(ls, "removeOnDbChange", 2); CLuaIHM::checkArgCount(ls, "removeOnDbChange", 2);
CLuaIHM::check(ls, CLuaIHM::isUIOnStack(ls, 1), "removeOnDbChange() requires a UI object in param 1"); CLuaIHM::check(ls, isUIOnStack(ls, 1), "removeOnDbChange() requires a UI object in param 1");
CLuaIHM::check(ls, ls.isString(2), "removeOnDbChange() requires a string in param 2"); CLuaIHM::check(ls, ls.isString(2), "removeOnDbChange() requires a string in param 2");
// retrieve args // retrieve args
CInterfaceElement *pIE= CLuaIHM::getUIOnStack(ls, 1); CInterfaceElement *pIE= getUIOnStack(ls, 1);
std::string dbList; std::string dbList;
ls.toString(2, dbList); ls.toString(2, dbList);
@ -565,12 +1159,12 @@ int CLuaIHMRyzom::runAH(CLuaState &ls)
// params: CInterfaceElement *, "ah", "params". // params: CInterfaceElement *, "ah", "params".
// return: none // return: none
CLuaIHM::checkArgCount(ls, "runAH", 3); CLuaIHM::checkArgCount(ls, "runAH", 3);
CLuaIHM::check(ls, CLuaIHM::isUIOnStack(ls, 1) || ls.isNil(1), "runAH() requires a UI object in param 1 (or Nil)"); CLuaIHM::check(ls, isUIOnStack(ls, 1) || ls.isNil(1), "runAH() requires a UI object in param 1 (or Nil)");
CLuaIHM::check(ls, ls.isString(2), "runAH() requires a string in param 2"); CLuaIHM::check(ls, ls.isString(2), "runAH() requires a string in param 2");
CLuaIHM::check(ls, ls.isString(3), "runAH() requires a string in param 3"); CLuaIHM::check(ls, ls.isString(3), "runAH() requires a string in param 3");
// retrieve args // retrieve args
CInterfaceElement *pIE= CLuaIHM::getUIOnStack(ls, 1); CInterfaceElement *pIE= getUIOnStack(ls, 1);
std::string ah, params; std::string ah, params;
ls.toString(2, ah); ls.toString(2, ah);
ls.toString(3, params); ls.toString(3, params);
@ -606,7 +1200,7 @@ int CLuaIHMRyzom::runExpr(CLuaState &ls)
ls.toString(1, expr); ls.toString(1, expr);
// run expression and push result // run expression and push result
return CLuaIHM::runExprAndPushResult(ls, expr); return runExprAndPushResult(ls, expr);
} }
// *************************************************************************** // ***************************************************************************
@ -654,7 +1248,7 @@ int CLuaIHMRyzom::runFct(CLuaState &ls)
// run expression and push result // run expression and push result
return CLuaIHM::runExprAndPushResult(ls, expr); return runExprAndPushResult(ls, expr);
} }
// *************************************************************************** // ***************************************************************************
@ -780,10 +1374,10 @@ int CLuaIHMRyzom::deleteUI(CLuaState &ls)
// params: CInterfaceElement * // params: CInterfaceElement *
// return: none // return: none
CLuaIHM::checkArgCount(ls, "deleteUI", 1); CLuaIHM::checkArgCount(ls, "deleteUI", 1);
CLuaIHM::check(ls, CLuaIHM::isUIOnStack(ls, 1), "deleteUI() requires a UI object in param 1"); CLuaIHM::check(ls, isUIOnStack(ls, 1), "deleteUI() requires a UI object in param 1");
// retrieve args // retrieve args
CInterfaceElement *pIE= CLuaIHM::getUIOnStack(ls, 1); CInterfaceElement *pIE= getUIOnStack(ls, 1);
if(!pIE) if(!pIE)
return 0; return 0;
@ -848,10 +1442,10 @@ int CLuaIHMRyzom::dumpUI(CLuaState &ls)
// params: CInterfaceElement * // params: CInterfaceElement *
// return: none // return: none
CLuaIHM::checkArgCount(ls, "dumpUI", 1); CLuaIHM::checkArgCount(ls, "dumpUI", 1);
CLuaIHM::check(ls, CLuaIHM::isUIOnStack(ls, 1), "dumpUI() requires a UI object in param 1"); CLuaIHM::check(ls, isUIOnStack(ls, 1), "dumpUI() requires a UI object in param 1");
// retrieve args // retrieve args
CInterfaceElement *pIE= CLuaIHM::getUIOnStack(ls, 1); CInterfaceElement *pIE= getUIOnStack(ls, 1);
if(!pIE) if(!pIE)
debugInfo("UI: NULL"); debugInfo("UI: NULL");
else else
@ -904,7 +1498,7 @@ int CLuaIHMRyzom::setTopWindow(CLuaState &ls)
//H_AUTO(Lua_CLuaIHM_setTopWindow) //H_AUTO(Lua_CLuaIHM_setTopWindow)
const char *funcName = "setTopWindow"; const char *funcName = "setTopWindow";
CLuaIHM::checkArgCount(ls, funcName, 1); CLuaIHM::checkArgCount(ls, funcName, 1);
CInterfaceGroup *wnd = dynamic_cast<CInterfaceGroup *>(CLuaIHM::getUIOnStack(ls, 1)); CInterfaceGroup *wnd = dynamic_cast<CInterfaceGroup *>( getUIOnStack(ls, 1));
if (!wnd) if (!wnd)
{ {
CLuaIHM::fails(ls, "%s : interface group expected as arg 1", funcName); CLuaIHM::fails(ls, "%s : interface group expected as arg 1", funcName);
@ -1030,8 +1624,8 @@ int CLuaIHMRyzom::setTextFormatTaged(CLuaState &ls)
CLuaIHM::checkArgCount(ls, "setTextFormatTaged", 2); CLuaIHM::checkArgCount(ls, "setTextFormatTaged", 2);
// *** check and retrieve param 1 // *** check and retrieve param 1
CLuaIHM::check(ls, CLuaIHM::isUIOnStack(ls, 1), "setTextFormatTaged() requires a UI object in param 1"); CLuaIHM::check(ls, isUIOnStack(ls, 1), "setTextFormatTaged() requires a UI object in param 1");
CInterfaceElement *pIE= CLuaIHM::getUIOnStack(ls, 1); CInterfaceElement *pIE= getUIOnStack(ls, 1);
// *** check and retrieve param 2. must be a string or a ucstring // *** check and retrieve param 2. must be a string or a ucstring
ucstring text; ucstring text;
@ -1392,10 +1986,10 @@ int CLuaIHMRyzom::enableModalWindow(CLuaState &ls)
const char *funcName = "enableModalWindow"; const char *funcName = "enableModalWindow";
CLuaIHM::checkArgCount(ls, funcName, 2); CLuaIHM::checkArgCount(ls, funcName, 2);
CLuaIHM::check(ls, CLuaIHM::isUIOnStack(ls, 1), "enableModalWindow() requires a UI object in param 1"); CLuaIHM::check(ls, isUIOnStack(ls, 1), "enableModalWindow() requires a UI object in param 1");
CLuaIHM::checkArgType(ls, funcName, 2, LUA_TSTRING); CLuaIHM::checkArgType(ls, funcName, 2, LUA_TSTRING);
CInterfaceElement *pIE= CLuaIHM::getUIOnStack(ls, 1); CInterfaceElement *pIE= getUIOnStack(ls, 1);
std::string modalId = ls.toString(2); std::string modalId = ls.toString(2);
// convert to id // convert to id
@ -1612,10 +2206,10 @@ int CLuaIHMRyzom::disableContextHelpForControl(CLuaState &ls)
// params: CCtrlBase* // params: CCtrlBase*
// return: none // return: none
CLuaIHM::checkArgCount(ls, "disableContextHelpForControl", 1); CLuaIHM::checkArgCount(ls, "disableContextHelpForControl", 1);
CLuaIHM::check(ls, CLuaIHM::isUIOnStack(ls, 1), "disableContextHelpForControl() requires a UI object in param 1"); CLuaIHM::check(ls, isUIOnStack(ls, 1), "disableContextHelpForControl() requires a UI object in param 1");
// retrieve args // retrieve args
CInterfaceElement *pIE= CLuaIHM::getUIOnStack(ls, 1); CInterfaceElement *pIE= getUIOnStack(ls, 1);
// go // go
CInterfaceManager *pIM= CInterfaceManager::getInstance(); CInterfaceManager *pIM= CInterfaceManager::getInstance();
@ -1815,7 +2409,7 @@ int CLuaIHMRyzom::getUICaller(CLuaState &ls)
} }
else else
{ {
CLuaIHM::pushUIOnStack(ls, pIE); pushUIOnStack(ls, pIE);
} }
return 1; return 1;
} }
@ -1833,7 +2427,7 @@ int CLuaIHMRyzom::getCurrentWindowUnder(CLuaState &ls)
} }
else else
{ {
CLuaIHM::pushUIOnStack(ls, pIE); pushUIOnStack(ls, pIE);
} }
return 1; return 1;
} }
@ -1847,10 +2441,10 @@ int CLuaIHMRyzom::getUIId(CLuaState &ls)
// params: CInterfaceElement* // params: CInterfaceElement*
// return: "ui:interface:...". (empty if error) // return: "ui:interface:...". (empty if error)
CLuaIHM::checkArgCount(ls, "getUIId", 1); CLuaIHM::checkArgCount(ls, "getUIId", 1);
CLuaIHM::check(ls, CLuaIHM::isUIOnStack(ls, 1), "getUIId() requires a UI object in param 1"); CLuaIHM::check(ls, isUIOnStack(ls, 1), "getUIId() requires a UI object in param 1");
// retrieve args // retrieve args
CInterfaceElement *pIE= CLuaIHM::getUIOnStack(ls, 1); CInterfaceElement *pIE= getUIOnStack(ls, 1);
// convert to id // convert to id
if(pIE) if(pIE)
@ -1870,10 +2464,10 @@ int CLuaIHMRyzom::getIndexInDB(CLuaState &ls)
// params: CDBCtrlSheet* // params: CDBCtrlSheet*
// return: index in DB of a dbctrlsheet (empty if error) // return: index in DB of a dbctrlsheet (empty if error)
CLuaIHM::checkArgCount(ls, "getIndexInDB", 1); CLuaIHM::checkArgCount(ls, "getIndexInDB", 1);
CLuaIHM::check(ls, CLuaIHM::isUIOnStack(ls, 1), "getIndexInDB() requires a UI object in param 1"); CLuaIHM::check(ls, isUIOnStack(ls, 1), "getIndexInDB() requires a UI object in param 1");
// retrieve args // retrieve args
CInterfaceElement *pIE= CLuaIHM::getUIOnStack(ls, 1); CInterfaceElement *pIE= getUIOnStack(ls, 1);
CDBCtrlSheet *pCS= dynamic_cast<CDBCtrlSheet*>(pIE); CDBCtrlSheet *pCS= dynamic_cast<CDBCtrlSheet*>(pIE);
// get the index in db // get the index in db
@ -1919,7 +2513,7 @@ int CLuaIHMRyzom::createGroupInstance(CLuaState &ls)
} }
else else
{ {
CLuaIHM::pushUIOnStack(ls, result); pushUIOnStack(ls, result);
} }
return 1; return 1;
} }
@ -1966,7 +2560,7 @@ int CLuaIHMRyzom::createRootGroupInstance(CLuaState &ls)
if (pRoot) if (pRoot)
pRoot->addGroup(result); pRoot->addGroup(result);
result->setActive(true); result->setActive(true);
CLuaIHM::pushUIOnStack(ls, result); pushUIOnStack(ls, result);
} }
return 1; return 1;
} }
@ -2005,7 +2599,7 @@ int CLuaIHMRyzom::createUIElement(CLuaState &ls)
} }
else else
{ {
CLuaIHM::pushUIOnStack(ls, result); pushUIOnStack(ls, result);
} }
return 1; return 1;
} }
@ -2256,7 +2850,7 @@ void CLuaIHMRyzom::debugInfo(const std::string &cstDbg)
if (ClientCfg.LuaDebugInfoGotoButtonEnabled) if (ClientCfg.LuaDebugInfoGotoButtonEnabled)
{ {
CInterfaceManager *pIM= CInterfaceManager::getInstance(); CInterfaceManager *pIM= CInterfaceManager::getInstance();
lua_State *ls = pIM->getLuaState()->getStatePointer(); lua_State *ls = CLuaManager::getInstance().getLuaState()->getStatePointer();
lua_Debug luaDbg; lua_Debug luaDbg;
if(lua_getstack (ls, 1, &luaDbg)) if(lua_getstack (ls, 1, &luaDbg))
{ {
@ -2305,7 +2899,7 @@ void CLuaIHMRyzom::dumpCallStack(int startStackLevel)
{ {
lua_Debug dbg; lua_Debug dbg;
CInterfaceManager *pIM= CInterfaceManager::getInstance(); CInterfaceManager *pIM= CInterfaceManager::getInstance();
lua_State *ls = pIM->getLuaState()->getStatePointer(); lua_State *ls = CLuaManager::getInstance().getLuaState()->getStatePointer();
int stackLevel = startStackLevel; int stackLevel = startStackLevel;
rawDebugInfo("Call stack : "); rawDebugInfo("Call stack : ");
rawDebugInfo("-------------"); rawDebugInfo("-------------");
@ -2328,7 +2922,7 @@ void CLuaIHMRyzom::getCallStackAsString(int startStackLevel /*=0*/,std::string &
result.clear(); result.clear();
lua_Debug dbg; lua_Debug dbg;
CInterfaceManager *pIM= CInterfaceManager::getInstance(); CInterfaceManager *pIM= CInterfaceManager::getInstance();
lua_State *ls = pIM->getLuaState()->getStatePointer(); lua_State *ls = CLuaManager::getInstance().getLuaState()->getStatePointer();
int stackLevel = startStackLevel; int stackLevel = startStackLevel;
result += "Call stack : \n"; result += "Call stack : \n";
result += "-------------"; result += "-------------";
@ -3269,3 +3863,75 @@ std::string CLuaIHMRyzom::createGotoFileButtonTag(const char *fileName, uint lin
} }
return ""; return "";
} }
// ***************************************************************************
int CLuaIHMRyzom::runExprAndPushResult(CLuaState &ls, const std::string &expr)
{
//H_AUTO(Lua_CLuaIHM_runExprAndPushResult)
// Execute expression
CInterfaceExprValue value;
if (CInterfaceExpr::eval(expr, value, NULL))
{
switch(value.getType())
{
case CInterfaceExprValue::Boolean:
ls.push(value.getBool());
break;
case CInterfaceExprValue::Integer:
ls.push((double)value.getInteger());
break;
case CInterfaceExprValue::Double:
ls.push(value.getDouble());
break;
case CInterfaceExprValue::String:
{
ucstring ucstr= value.getUCString();
// Yoyo: dynamically decide whether must return a string or a ucstring
bool mustUseUCString= false;
for (uint i = 0; i < ucstr.size (); i++)
{
if (ucstr[i] > 255)
{
mustUseUCString= true;
break;
}
}
// push a ucstring?
if(mustUseUCString)
{
#if LUABIND_VERSION > 600
luabind::detail::push(ls.getStatePointer(), ucstr);
#else
luabind::object obj(ls.getStatePointer(), ucstr);
obj.pushvalue();
#endif
}
else
{
ls.push(ucstr.toString());
}
break;
}
case CInterfaceExprValue::RGBA:
{
CRGBA color = value.getRGBA();
#if LUABIND_VERSION > 600
luabind::detail::push(ls.getStatePointer(), color);
#else
luabind::object obj(ls.getStatePointer(), color);
obj.pushvalue();
#endif
break;
}
break;
case CInterfaceExprValue::UserType: // Yoyo: don't care UserType...
default:
ls.pushNil();
break;
}
}
else
ls.pushNil();
return 1;
}

View file

@ -11,6 +11,25 @@ public:
private: private:
static void createLuaEnumTable(CLuaState &ls, const std::string &str); static void createLuaEnumTable(CLuaState &ls, const std::string &str);
static int luaClientCfgIndex(CLuaState &ls);
static int luaClientCfgNewIndex(CLuaState &ls);
// Functions for the ui metatable
static class CInterfaceElement *getUIRelative(class CInterfaceElement *pIE, const std::string &propName);
static int luaUIIndex(CLuaState &ls);
static int luaUINewIndex(CLuaState &ls);
static int luaUIEq(CLuaState &ls);
static int luaUINext(CLuaState &ls);
static int luaUIDtor(CLuaState &ls);
// CInterfaceElement management on stack, stored by a CRefPtr.
public:
static void pushUIOnStack(CLuaState &ls, class CInterfaceElement *pIE);
static bool isUIOnStack(CLuaState &ls, sint index);
static CInterfaceElement *getUIOnStack(CLuaState &ls, sint index);
static void checkArgTypeUIElement(CLuaState &ls, const char *funcName, uint index);
private:
static int getUI(CLuaState &ls); // params: "ui:interface:...". return: CInterfaceElement* (nil if error), an additionnal boolean parameter static int getUI(CLuaState &ls); // params: "ui:interface:...". return: CInterfaceElement* (nil if error), an additionnal boolean parameter
// LUA exported Functions with standard lua (because use ui object, use variable param number, or return dynamic-typed object) // LUA exported Functions with standard lua (because use ui object, use variable param number, or return dynamic-typed object)
@ -251,6 +270,8 @@ public:
// Requires that 'ClientCfg.LuaDebugInfoGotoButtonEnabled' is set to 1, else // Requires that 'ClientCfg.LuaDebugInfoGotoButtonEnabled' is set to 1, else
// a, empty tag is returned // a, empty tag is returned
static std::string createGotoFileButtonTag(const char *fileName, uint line); static std::string createGotoFileButtonTag(const char *fileName, uint line);
static int runExprAndPushResult(CLuaState &ls, const std::string &expr); // Used by runExpr and runFct
}; };
#endif #endif

View file

@ -0,0 +1,34 @@
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "lua_manager.h"
#include "nel/gui/lua_helper.h"
bool CLuaManager::debugLua = false;
CLuaManager* CLuaManager::instance = NULL;
CLuaManager::CLuaManager()
{
luaState = new NLGUI::CLuaState( debugLua );
}
CLuaManager::~CLuaManager()
{
luaState = NULL;
}

View file

@ -0,0 +1,57 @@
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef LUA_MANAGER_H
#define LUA_MANAGER_H
#include "nel/misc/smart_ptr.h"
namespace NLGUI
{
class CLuaState;
}
/// Provides a single global access point to the Lua state, and related stuff. :(
class CLuaManager
{
public:
~CLuaManager();
static CLuaManager& getInstance()
{
if( instance == NULL )
{
instance = new CLuaManager();
}
return *instance;
}
/// Enables attaching the Lua debugger in the CLuaState instance, only matters on startup.
static void enableLuaDebugging(){ debugLua = true; }
NLGUI::CLuaState* getLuaState() const{ return luaState; }
private:
CLuaManager();
static CLuaManager *instance;
static bool debugLua;
NLMISC::CSmartPtr< NLGUI::CLuaState > luaState;
};
#endif

View file

@ -17,7 +17,7 @@
//#include "stdpch.h" //#include "stdpch.h"
#include "lua_object.h" #include "lua_object.h"
#include "lua_ihm.h" #include "lua_ihm.h"
#include "lua_ihm_ryzom.h" //#include "lua_ihm_ryzom.h"
#include "nel/gui/lua_helper.h" #include "nel/gui/lua_helper.h"
using namespace NLGUI; using namespace NLGUI;
// //
@ -617,7 +617,7 @@ void CLuaObject::dump(uint maxDepth /*= 20*/, std::set<const void *> *alreadySee
} }
catch(const std::exception &e) catch(const std::exception &e)
{ {
CLuaIHMRyzom::dumpCallStack(); //CLuaIHMRyzom::dumpCallStack();
nlwarning(e.what()); nlwarning(e.what());
} }
} }

View file

@ -15,9 +15,6 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdpch.h"
#include "reflect.h" #include "reflect.h"
// Yoyo: Act like a singleton, else registerClass may crash. // Yoyo: Act like a singleton, else registerClass may crash.
@ -132,4 +129,63 @@ const CReflectedProperty *CReflectable::getReflectedProperty(const std::string &
} }
#include "lua_manager.h"
CReflectableRefPtrTarget::~CReflectableRefPtrTarget()
{
CLuaState *lua= CLuaManager::getInstance().getLuaState();
if(!lua)
return;
CLuaStackChecker lsc(lua);
// remove from the lua registry if i'm in
lua->pushLightUserData((void *) this);
lua->getTable(LUA_REGISTRYINDEX);
if (!lua->isNil(-1))
{
lua->pop();
lua->pushLightUserData((void *) this);
lua->pushNil();
lua->setTable(LUA_REGISTRYINDEX);
}
else
{
lua->pop();
}
}
/**
* Data structure pushed in lua (a userdata) to access CReflectableRefPtrTarget derived objects
* These includes element of the GUI.
* if holds a pointer to the reflectable object, and
* a cache to its CClassInfo for fast access to exported properties
* \see reflect.h
*/
//
inline const CClassInfo &CReflectableLuaRef::getClassInfo() const
{
nlassert(Ptr); // class info should not be accessed for a null ptr
if (_ClassInfo) return *_ClassInfo;
_ClassInfo = Ptr->getClassInfo();
return *_ClassInfo;
}
const CReflectedProperty *CReflectableLuaRef::getProp(const char *luaStringPtr) const
{
const CClassInfo &ci = getClassInfo();
CClassInfo::TLuaStrToPropMap::const_iterator it = ci.LuaStrToProp.find(luaStringPtr);
if (it != ci.LuaStrToProp.end())
{
return it->second.Prop;
}
// slowly retrieve property, and store in cache
// NB nico : this could also be done at startup...
const CReflectedProperty *prop = CReflectSystem::getProperty(ci.ClassName, luaStringPtr, false);
if (!prop) return NULL;
CLuaIndexedProperty lip;
lip.Id = CLuaString(luaStringPtr); // keep a ref on the lua string to ensure that its pointer always remains valid
lip.Prop = prop;
ci.LuaStrToProp[luaStringPtr] = lip;
return prop;
}

View file

@ -340,10 +340,31 @@ private:
/** Reflectable refcounted object
* NB nico : added this intermediate class so that the binding from lua to the reflection
* system that are found in CLuaIHM can be reused for other objects as well
* NOTE: The class is named 'CReflectableRefPtrTarget' and not 'CReflectableRefCount'
* because the refcount part is only used for ref pointing in the ui
*/
class CReflectableRefPtrTarget : public CReflectable, public NLMISC::CRefCount
{
public:
virtual ~CReflectableRefPtrTarget();
};
class CReflectableLuaRef
{
public:
CReflectableLuaRef(CReflectableRefPtrTarget *ptr = NULL) : Ptr(ptr), _ClassInfo(NULL) {}
NLMISC::CRefPtr<CReflectableRefPtrTarget> Ptr;
const CClassInfo &getClassInfo() const;
// IMPORTANT : luaStringPtr should have been obtained from lua, see remark in CClassInfo
const CReflectedProperty *getProp(const char *luaStringPtr) const;
private:
// cache to class definition of the pointee object (once a CReflectableLuaRef created in lua, it remains a *const* pointer)
mutable const CClassInfo *_ClassInfo;
};
#endif #endif

View file

@ -112,6 +112,7 @@
#include "connection.h" #include "connection.h"
#include "landscape_poly_drawer.h" #include "landscape_poly_drawer.h"
#include "interface_v3/lua_ihm.h" #include "interface_v3/lua_ihm.h"
#include "interface_v3/lua_ihm_ryzom.h"
#include "far_tp.h" #include "far_tp.h"
#include "session_browser_impl.h" #include "session_browser_impl.h"
#include "bg_downloader_access.h" #include "bg_downloader_access.h"
@ -144,6 +145,8 @@
#include "interface_v3/bot_chat_manager.h" #include "interface_v3/bot_chat_manager.h"
#include "string_manager_client.h" #include "string_manager_client.h"
#include "interface_v3/lua_manager.h"
/////////// ///////////
// USING // // USING //
@ -1514,7 +1517,7 @@ bool mainLoop()
R2::getEditor().waitScenario(); R2::getEditor().waitScenario();
} }
CSessionBrowserImpl::getInstance().init(CInterfaceManager::getInstance()->getLuaState()); CSessionBrowserImpl::getInstance().init(CLuaManager::getInstance().getLuaState());
} }
CInterfaceManager::getInstance()->executeLuaScript("game:onMainLoopBegin()"); CInterfaceManager::getInstance()->executeLuaScript("game:onMainLoopBegin()");
@ -2977,7 +2980,7 @@ bool mainLoop()
} // end of main loop } // end of main loop
CInterfaceManager *im = CInterfaceManager::getInstance(); CInterfaceManager *im = CInterfaceManager::getInstance();
if (im->getLuaState()) if (CLuaManager::getInstance().getLuaState())
{ {
CInterfaceManager::getInstance()->executeLuaScript("game:onMainLoopEnd()"); CInterfaceManager::getInstance()->executeLuaScript("game:onMainLoopEnd()");
} }
@ -3228,11 +3231,10 @@ class CHandlerDebugUiDumpElementUnderMouse : public IActionHandler
virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) virtual void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
{ {
if (HighlightedDebugUI == NULL) return; if (HighlightedDebugUI == NULL) return;
CInterfaceManager *pIM = CInterfaceManager::getInstance(); CLuaState *lua = CLuaManager::getInstance().getLuaState();
CLuaState *lua = pIM->getLuaState();
if (!lua) return; if (!lua) return;
CLuaStackRestorer lsr(lua, 0); CLuaStackRestorer lsr(lua, 0);
CLuaIHM::pushUIOnStack(*lua, HighlightedDebugUI); CLuaIHMRyzom::pushUIOnStack(*lua, HighlightedDebugUI);
lua->pushValue(LUA_GLOBALSINDEX); lua->pushValue(LUA_GLOBALSINDEX);
CLuaObject env(*lua); CLuaObject env(*lua);
env["inspect"].callNoThrow(1, 0); env["inspect"].callNoThrow(1, 0);
@ -3403,9 +3405,9 @@ void displayDebug()
line-= 2 * lineStep; line-= 2 * lineStep;
// Lua stuffs // Lua stuffs
CInterfaceManager *pIM = CInterfaceManager::getInstance(); CInterfaceManager *pIM = CInterfaceManager::getInstance();
TextContext->printfAt(0.0f, line, "Lua mem (kb) : %d / %d", pIM->getLuaState()->getGCCount(), pIM->getLuaState()->getGCThreshold()); TextContext->printfAt(0.0f, line, "Lua mem (kb) : %d / %d", CLuaManager::getInstance().getLuaState()->getGCCount(), CLuaManager::getInstance().getLuaState()->getGCThreshold());
line-= lineStep; line-= lineStep;
TextContext->printfAt(0.0f, line, "Lua stack size = %d", pIM->getLuaState()->getTop()); TextContext->printfAt(0.0f, line, "Lua stack size = %d", CLuaManager::getInstance().getLuaState()->getTop());
line-= lineStep; line-= lineStep;
#endif #endif

View file

@ -113,6 +113,7 @@ using namespace NLGUI;
#include "../session_browser_impl.h" #include "../session_browser_impl.h"
#include "../far_tp.h" #include "../far_tp.h"
#include "../interface_v3/lua_manager.h"
using namespace NLMISC; using namespace NLMISC;
@ -587,7 +588,7 @@ CLuaState &CEditor::getLua()
{ {
//H_AUTO(R2_CEditor_getLua) //H_AUTO(R2_CEditor_getLua)
CHECK_EDITOR CHECK_EDITOR
CLuaState *ls = getUI().getLuaState(); CLuaState *ls = CLuaManager::getInstance().getLuaState();
nlassert(ls); nlassert(ls);
return *ls; return *ls;
} }
@ -3953,7 +3954,7 @@ void CEditor::release()
} }
// clear the environment // clear the environment
if (getUI().getLuaState()) if (CLuaManager::getInstance().getLuaState())
{ {
getLua().push(R2_LUA_PATH); getLua().push(R2_LUA_PATH);
getLua().pushNil(); getLua().pushNil();

View file

@ -90,6 +90,7 @@
#include "faction_war_manager.h" #include "faction_war_manager.h"
#include "interface_v3/interface_ddx.h" #include "interface_v3/interface_ddx.h"
#include "bg_downloader_access.h" #include "bg_downloader_access.h"
#include "interface_v3/lua_manager.h"
/////////// ///////////
@ -633,6 +634,8 @@ void release()
CInterfaceExpr::release(); CInterfaceExpr::release();
CPdrTokenRegistry::releaseInstance(); CPdrTokenRegistry::releaseInstance();
NLNET::IModuleManager::releaseInstance(); NLNET::IModuleManager::releaseInstance();
delete &CLuaManager::getInstance();