CHANGED: #1471 Modularized CInterfaceParser. It is now extendable with parser modules, so it can parse Ryzom game related stuff without the parser code having to be in the class itself.

This commit is contained in:
dfighter1985 2012-07-09 02:36:17 +02:00
parent 4ed62dc1c4
commit 7142b94449
6 changed files with 734 additions and 583 deletions

View file

@ -747,11 +747,20 @@ const CActionsManager::CCategoryLocator *CActionsManager::getActionLocator (cons
while ((ite != _ActionCategory.end ()) && (ite->first == name.Name)) while ((ite != _ActionCategory.end ()) && (ite->first == name.Name))
{ {
// Ref on the base action // Ref on the base action
const CBaseAction &baseAction = _Categories[ite->second.CategoryId].BaseActions[ite->second.BaseActionId]; const CCategory &cat = _Categories[ite->second.CategoryId];
uint baseActionId = ite->second.BaseActionId;
uint baseActionSize = cat.BaseActions.size();
if( ite->second.BaseActionId >= cat.BaseActions.size() )
return NULL;
const CBaseAction &baseAction = cat.BaseActions[ite->second.BaseActionId];
// Check parameters // Check parameters
uint i; uint i;
for (i=0; i<baseAction.Parameters.size (); i++) uint s = baseAction.Parameters.size();
for (i=0; i<s; i++)
{ {
bool parameterOk = false; bool parameterOk = false;
const CBaseAction::CParameter &parameter = baseAction.Parameters[i]; const CBaseAction::CParameter &parameter = baseAction.Parameters[i];

View file

@ -128,6 +128,8 @@ using namespace NLGUI;
#include "../bg_downloader_access.h" #include "../bg_downloader_access.h"
#include "parser_modules.h"
using namespace NLMISC; using namespace NLMISC;
namespace NLGUI namespace NLGUI
@ -397,6 +399,15 @@ namespace
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
CInterfaceManager::CInterfaceManager( NL3D::UDriver *driver, NL3D::UTextContext *textcontext ) CInterfaceManager::CInterfaceManager( NL3D::UDriver *driver, NL3D::UTextContext *textcontext )
{ {
addModule( "scene3d", new CIF3DSceneParser() );
addModule( "ddx", new CIFDDXParser() );
addModule( "action_category", new CActionCategoryParser() );
addModule( "command", new CCommandParser() );
addModule( "key", new CKeyParser() );
addModule( "macro", new CMacroParser() );
setCacheUIParsing( ClientCfg.CacheUIParsing );
CWidgetManager::parser = this; CWidgetManager::parser = this;
this->driver = driver; this->driver = driver;
this->textcontext = textcontext; this->textcontext = textcontext;

View file

@ -34,11 +34,8 @@
#include "nel/gui/lua_ihm.h" #include "nel/gui/lua_ihm.h"
#include "nel/gui/lua_manager.h" #include "nel/gui/lua_manager.h"
#include "interface_3d_scene.h"
#include "lua_ihm_ryzom.h" #include "lua_ihm_ryzom.h"
#include "interface_ddx.h"
#include "macrocmd_manager.h"
#include "../commands.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
@ -47,6 +44,7 @@ const uint32 UI_CACHE_SERIAL_CHECK = (uint32) 'IUG_';
using namespace NLMISC; using namespace NLMISC;
using namespace NLGUI; using namespace NLGUI;
using namespace std;
void saveXMLTree(COFile &f, xmlNodePtr node) void saveXMLTree(COFile &f, xmlNodePtr node)
{ {
@ -114,17 +112,6 @@ xmlNodePtr buildTree(CIFile &f)
// ----------------------------------------------------------------------------
extern CActionsManager Actions; // Actions Manager.
extern CActionsManager EditActions; // Actions Manager.
extern CActionsContext ActionsContext; // Actions context.
// ----------------------------------------------------------------------------
using namespace NLMISC;
using namespace std;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// CRootGroup // CRootGroup
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -212,11 +199,13 @@ CInterfaceParser::CInterfaceParser()
{ {
// LUA // LUA
_LuaState= NULL; _LuaState= NULL;
cacheUIParsing = false;
} }
CInterfaceParser::~CInterfaceParser() CInterfaceParser::~CInterfaceParser()
{ {
_LuaState = NULL; _LuaState = NULL;
removeAllModules();
} }
/** Convert a string into a memstream /** Convert a string into a memstream
*/ */
@ -328,7 +317,7 @@ bool CInterfaceParser::parseInterface (const std::vector<std::string> & strings,
xmlNodePtr cur = NULL; xmlNodePtr cur = NULL;
bool saveParseResult = false; bool saveParseResult = false;
bool readFromUncompressedXML = true; bool readFromUncompressedXML = true;
if( false /* isFilename && ClientCfg.CacheUIParsing */ ) if( isFilename && cacheUIParsing )
{ {
saveParseResult = true; saveParseResult = true;
std::string archive = CPath::lookup(nextFileName + "_compressed", false, false); std::string archive = CPath::lookup(nextFileName + "_compressed", false, false);
@ -457,11 +446,6 @@ bool CInterfaceParser::parseXMLDocument(xmlNodePtr root, bool reload)
//parse templates //parse templates
xmlNodePtr curNode = root->children; xmlNodePtr curNode = root->children;
// Resize action category array
uint actionCategoryCount = CIXml::countChildren(curNode, "action_category");
Actions.reserveCategories((uint)Actions.getCategories ().size()+actionCategoryCount);
EditActions.reserveCategories(1);
std::vector< CWidgetManager::SMasterGroup > &_MasterGroups = CWidgetManager::getInstance()->getAllMasterGroup(); std::vector< CWidgetManager::SMasterGroup > &_MasterGroups = CWidgetManager::getInstance()->getAllMasterGroup();
while (curNode) while (curNode)
@ -515,30 +499,20 @@ bool CInterfaceParser::parseXMLDocument(xmlNodePtr root, bool reload)
// todo hulud interface syntax error // todo hulud interface syntax error
nlwarning ("could not parse define"); nlwarning ("could not parse define");
} }
else if ( !strcmp((char*)curNode->name,"action_category") )
{
if (!parseActionCategory(curNode))
// todo hulud interface syntax error
nlwarning ("could not parse action_category");
}
else if ( !strcmp((char*)curNode->name,"key") )
{
parseKey(curNode);
}
else if ( !strcmp((char*)curNode->name,"macro") )
{
parseMacro(curNode);
}
else if ( !strcmp((char*)curNode->name,"command") )
{
parseCommand(curNode);
}
else if ( !strcmp((char*)curNode->name,"style") ) else if ( !strcmp((char*)curNode->name,"style") )
{ {
if (!parseStyle(curNode)) if (!parseStyle(curNode))
// todo hulud interface syntax error // todo hulud interface syntax error
nlwarning ("could not parse 'style'"); nlwarning ("could not parse 'style'");
} }
else
{
IParserModule *module = getModuleFor( (char*)( curNode->name ) );
if( module != NULL ){
if( module->canParseInStage( IParserModule::Unresolved ) )
module->parse( curNode, rootGroup );
}
}
curNode = curNode->next; curNode = curNode->next;
} }
@ -647,18 +621,6 @@ bool CInterfaceParser::parseXMLDocument(xmlNodePtr root, bool reload)
// todo hulud interface syntax error // todo hulud interface syntax error
nlwarning ("could not parse 'anim'"); nlwarning ("could not parse 'anim'");
} }
else if ( !strcmp((char*)root->name,"scene3d") )
{
if (!parseScene3D(root,rootGroup))
// todo hulud interface syntax error
nlwarning ("could not parse 'scene3d'");
}
else if ( !strcmp((char*)root->name,"ddx") )
{
if (!parseDDX(root,rootGroup))
// todo hulud interface syntax error
nlwarning ("could not parse 'ddx'");
}
else if ( !strcmp((char*)root->name,"lua") ) else if ( !strcmp((char*)root->name,"lua") )
{ {
if(!parseLUAScript(root)) if(!parseLUAScript(root))
@ -667,6 +629,15 @@ bool CInterfaceParser::parseXMLDocument(xmlNodePtr root, bool reload)
exit( EXIT_FAILURE ); exit( EXIT_FAILURE );
} }
} }
else
{
IParserModule *module = getModuleFor( (char*)( root->name ) );
if( module != NULL )
{
if( module->canParseInStage( IParserModule::Resolved ) )
module->parse( root, rootGroup );
}
}
root = root->next; root = root->next;
} }
@ -860,78 +831,6 @@ bool CInterfaceParser::parseInstance(xmlNodePtr cur)
return true; return true;
} }
// ----------------------------------------------------------------------------
/*bool CInterfaceParser::parseDynamicList(xmlNodePtr cur, CInterfaceGroup * parentGroup)
{
CGroupListDynamic* li = new CGroupListDynamic;
if (!li->parse(cur,parentGroup))
{
nlinfo("failed to parse a dynamic list");
delete li;
return false;
}
//copy the templates used by the instance of the list, otherwise it will be scratched after init
xmlNodePtr listChild = cur->children;
//listChild should exist here otherwise li->parse would have returned false
nlassert(listChild);
CXMLAutoPtr buf = (char*) xmlGetProp( listChild, (xmlChar*)"template" );
if (!buf)
{
nlinfo(" dynamic list : the child instance has no template attribute");
return false;
}
for (vector<xmlNodePtr>::const_iterator it = _Templates.begin(); it != _Templates.end();it++)
{
CXMLAutoPtr ptr = (char*) xmlGetProp( *it, (xmlChar*)"name" );
if (!ptr)
{
nlinfo("no name in a template node");
return false;
}
if ( !strcmp(buf,ptr) )
{
break;
}
}
xmlNodePtr node = xmlCopyNode(*it,1);
_KeptTemplates.push_back(node);
CXMLAutoPtr dependencies = (char*) xmlGetProp( cur, (xmlChar*)"dependencies" );
if (dependencies)
{
char *seekPtr = dependencies.getDatas();
seekPtr = strtok(seekPtr," ,\t");
while (seekPtr)
{
for (vector<xmlNodePtr>::const_iterator it = _Templates.begin(); it != _Templates.end();it++)
{
CXMLAutoPtr ptr = (char*) xmlGetProp( *it, (xmlChar*)"name" );
if (!ptr)
{
nlinfo("no name in a template node");
return false;
}
if ( !strcmp(seekPtr, ptr) )
{
break;
}
}
xmlNodePtr node = xmlCopyNode(*it,1);
_KeptTemplates.push_back(node);
seekPtr = strtok(NULL," ,\t");
}
}
//add the list in the tree
if (parentGroup)
{
parentGroup->addGroup(li);
}
return true;
}*/
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
bool CInterfaceParser::parseVector(xmlNodePtr cur) bool CInterfaceParser::parseVector(xmlNodePtr cur)
{ {
@ -1349,10 +1248,15 @@ bool CInterfaceParser::parseGroupChildren(xmlNodePtr cur, CInterfaceGroup * pare
ok = ok && parseVector(cur); ok = ok && parseVector(cur);
else if ( !strcmp((char*)cur->name,"link") ) else if ( !strcmp((char*)cur->name,"link") )
ok = ok && parseLink(cur,parentGroup); ok = ok && parseLink(cur,parentGroup);
else if ( !strcmp((char*)cur->name,"scene3d") ) else
ok = ok && parseScene3D(cur,parentGroup); {
else if ( !strcmp((char*)cur->name,"ddx") ) IParserModule *module = getModuleFor( (char*)( cur->name ) );
ok = ok && parseDDX(cur,parentGroup); if( module != NULL )
{
if( module->canParseInStage( IParserModule::GroupChildren ) )
ok = ok && module->parse( cur, parentGroup );
}
}
cur = cur->next; cur = cur->next;
@ -1610,6 +1514,42 @@ bool CInterfaceParser::setupTreeNode (xmlNodePtr cur, CGroupContainer * /* paren
return true; return true;
} }
void CInterfaceParser::addModule( std::string name, IParserModule *module )
{
std::map< std::string, IParserModule* >::iterator itr =
moduleMap.find( name );
if( itr != moduleMap.end() )
{
nlwarning( "Tried to add parser module %s, which already exists.",name.c_str() );
delete module;
return;
}
module->setParser( this );
moduleMap[ name ] = module;
}
CInterfaceParser::IParserModule* CInterfaceParser::getModuleFor( std::string name ) const
{
std::map< std::string, IParserModule* >::const_iterator itr =
moduleMap.find( name );
if( itr == moduleMap.end() )
return NULL;
else
return itr->second;
}
void CInterfaceParser::removeAllModules()
{
std::map< std::string, IParserModule* >::iterator itr;
for( itr = moduleMap.begin(); itr != moduleMap.end(); ++itr )
{
delete itr->second;
}
moduleMap.clear();
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
bool CInterfaceParser::setupTree (xmlNodePtr cur, CWidgetManager::SMasterGroup * /* parentGroup */) bool CInterfaceParser::setupTree (xmlNodePtr cur, CWidgetManager::SMasterGroup * /* parentGroup */)
{ {
@ -2471,435 +2411,6 @@ bool CInterfaceParser::parseAnim(xmlNodePtr cur, CInterfaceGroup * parentGroup)
return true; return true;
} }
//==================================================================
bool CInterfaceParser::parseScene3D(xmlNodePtr cur, CInterfaceGroup * parentGroup)
{
H_AUTO(parseScene3D)
CInterface3DScene *pScene;
CXMLAutoPtr ptr;
pScene = new CInterface3DScene(CViewBase::TCtorParam());
// parse the group attributes
if (!pScene->parse(cur,parentGroup))
{
delete pScene;
// todo hulud interface syntax error
nlinfo ("cannot parse 3d scene attributes");
return false;
}
if (parentGroup)
{
CGroupList *pList = dynamic_cast<CGroupList*>(parentGroup);
if (pList != NULL)
pList->addChild (pScene);
else
parentGroup->addGroup (pScene);
}
else
{
string tmp = "no parent for "+pScene->getId();
// todo hulud interface syntax error
nlinfo (tmp.c_str());
delete pScene;
return false;
}
return true;
}
// ----------------------------------------------------------------------------
bool CInterfaceParser::parseActionCategory(xmlNodePtr cur)
{
H_AUTO(parseActionCategory)
// The category
CCategory category;
// Name
CXMLAutoPtr ptr((const char*) xmlGetProp( cur, (xmlChar*)"name" ));
if (ptr)
category.Name = (const char*)ptr;
// Localized string
ptr = (char*) xmlGetProp( cur, (xmlChar*)"hardtext" );
if (ptr)
category.LocalizedName = (const char*)ptr;
// macroisable (per category)
ptr = (char*) xmlGetProp( cur, (xmlChar*)"macroisable" );
if (ptr)
category.Macroisable= CInterfaceElement::convertBool(ptr);
// Count number of action
category.BaseActions.resize (CIXml::countChildren(cur, "action"));
std::string actionCategoryContext = "game";
ptr = (char*) xmlGetProp( cur, (xmlChar*)"contexts" );
if (ptr)
actionCategoryContext = (const char *) ptr;
uint actionIndex = 0;
xmlNodePtr actionNode = CIXml::getFirstChildNode(cur, "action");
if (actionNode)
{
do
{
// The action
CBaseAction &action = category.BaseActions[actionIndex];
// list of contexts in which this action is valid
ptr = (char*) xmlGetProp( actionNode, (xmlChar*)"contexts" );
if (ptr)
action.Contexts = (const char *) ptr;
else
action.Contexts = actionCategoryContext; // inherit from action category
// Repeat flag
ptr = (char*) xmlGetProp( actionNode, (xmlChar*)"repeat" );
if (ptr)
fromString((const char*)ptr, action.Repeat);
// KeyDown flag
ptr = (char*) xmlGetProp( actionNode, (xmlChar*)"keydown" );
if (ptr)
fromString((const char*)ptr, action.KeyDown);
// KeyUp flag
ptr = (char*) xmlGetProp( actionNode, (xmlChar*)"keyup" );
if (ptr)
fromString((const char*)ptr, action.KeyUp);
// WaitForServer flag (wait an answer from server before continuing)
ptr = (char*) xmlGetProp( actionNode, (xmlChar*)"waitforserver" );
if (ptr)
fromString((const char*)ptr, action.WaitForServer);
// Action name
ptr = (char*) xmlGetProp( actionNode, (xmlChar*)"name" );
if (ptr)
action.Name = (const char*)ptr;
// Action localized name
ptr = (char*) xmlGetProp( actionNode, (xmlChar*)"hardtext" );
if (ptr)
action.LocalizedName = (const char*)ptr;
// macroisable (per action)
action.Macroisable= true;
ptr = (char*) xmlGetProp( actionNode, (xmlChar*)"macroisable" );
if (ptr)
action.Macroisable = CInterfaceElement::convertBool(ptr);
// Read the parameters
action.Parameters.resize (CIXml::countChildren(actionNode, "parameter"));
uint parameterIndex = 0;
xmlNodePtr paramNode = CIXml::getFirstChildNode(actionNode, "parameter");
if (paramNode)
{
do
{
// The parameter
CBaseAction::CParameter &parameter = action.Parameters[parameterIndex];
// Parameter type
ptr = (char*) xmlGetProp( paramNode, (xmlChar*)"type" );
if (ptr)
{
sint32 tType;
fromString((const char*)ptr, tType);
parameter.Type = (CBaseAction::CParameter::TType)tType;
}
// Parameter name
ptr = (char*) xmlGetProp( paramNode, (xmlChar*)"name" );
if (ptr)
parameter.Name = (const char*)ptr;
// Parameter localized name
ptr = (char*) xmlGetProp( paramNode, (xmlChar*)"hardtext" );
if (ptr)
parameter.LocalizedName = (const char*)ptr;
// Default value
ptr = (char*) xmlGetProp( paramNode, (xmlChar*)"value" );
if (ptr)
parameter.DefaultValue = (const char*)ptr;
// Visible flag
//ptr = (char*) xmlGetProp( paramNode, (xmlChar*)"visible" );
//if (ptr)
// fromString((const char*)ptr, parameter.Visible);
// Parse instance
xmlNodePtr instanceNode = CIXml::getFirstChildNode(paramNode, "instance");
if (instanceNode)
{
do
{
if (!parseInstance(instanceNode))
{
// todo hulud interface syntax error
nlwarning("<CInterfaceParser::parseActionCategory> cannot create instance from template");
}
}
while((instanceNode = CIXml::getNextChildNode(instanceNode, "instance")));
}
parameter.Values.resize (CIXml::countChildren(paramNode, "value"));
uint valueIndex = 0;
xmlNodePtr valueNode = CIXml::getFirstChildNode(paramNode, "value");
if (valueNode)
{
do
{
// The value
CBaseAction::CParameter::CValue &value = parameter.Values[valueIndex];
// Value
ptr = (char*) xmlGetProp( valueNode, (xmlChar*)"value" );
if (ptr)
value.Value = (const char*)ptr;
// list of contexts in which this value is valid
ptr = (char*) xmlGetProp( valueNode, (xmlChar*)"contexts" );
if (ptr) value.Contexts = (const char*) ptr;
else value.Contexts = action.Contexts; // inherit context from action
// Localized value
ptr = (char*) xmlGetProp( valueNode, (xmlChar*)"hardtext" );
if (ptr)
value.LocalizedValue = (const char*)ptr;
valueIndex++;
}
while((valueNode = CIXml::getNextChildNode(valueNode, "value")));
}
parameterIndex++;
}
while((paramNode = CIXml::getNextChildNode(paramNode, "parameter")));
}
// Next action
actionIndex++;
}
while((actionNode = CIXml::getNextChildNode(actionNode, "action")));
}
// Add this category to the action manager
CActionsManager *actionManager = ActionsContext.getActionsManager (category.Name);
if (actionManager)
{
// They want to display debug shortcut in final version
#if FINAL_VERSION
if ((category.Name != "debug") || ClientCfg.AllowDebugCommands)
#else // FINAL_VERSION
if (1)
#endif // FINAL_VERSION
{
actionManager->removeCategory (category.Name);
actionManager->addCategory (category);
}
else
{
// Remove thoses actions from the manager
CAHManager *pAHFM = CAHManager::getInstance();
uint i;
for (i=0; i<category.BaseActions.size(); i++)
{
CAHManager::TFactoryMap::iterator ite = pAHFM->FactoryMap.find (category.BaseActions[i].Name);
if (ite != pAHFM->FactoryMap.end())
{
IActionHandler *ah = ite->second;
pAHFM->FactoryMap.erase (ite);
pAHFM->NameMap.erase (ah);
}
}
}
}
return true;
}
//==================================================================
bool CInterfaceParser::parseKey(xmlNodePtr cur)
{
H_AUTO(parseKey)
// Parse the key
bool ret = false;
// Localized string
TKey key;
CXMLAutoPtr ptrKey((const char*) xmlGetProp( cur, (xmlChar*)"name" ));
if (ptrKey)
{
bool isNA = string((const char*)ptrKey) == string("N/A");
// Get the key from the string
key = CEventKey::getKeyFromString ((const char*)ptrKey);
if (key != KeyCount || isNA)
{
// Get the action
CXMLAutoPtr ptrAction((const char*) xmlGetProp( cur, (xmlChar*)"action" ));
if (ptrAction)
{
// Get the params
CXMLAutoPtr ptrParams((const char*) xmlGetProp( cur, (xmlChar*)"params" ));
// Get the modifiers
bool shift=false;
bool ctrl=false;
bool menu=false;
CXMLAutoPtr ptr((const char*) xmlGetProp( cur, (xmlChar*)"shift" ));
if (ptr)
fromString((const char*)ptr, shift);
ptr = (char*) xmlGetProp( cur, (xmlChar*)"ctrl" );
if (ptr)
fromString((const char*)ptr, ctrl);
ptr = (char*) xmlGetProp( cur, (xmlChar*)"menu" );
if (ptr)
fromString((const char*)ptr, menu);
// Repeat flag
bool repeat=false;
ptr = (char*) xmlGetProp( cur, (xmlChar*)"repeat" );
if (ptr)
fromString((const char*)ptr, repeat);
// Get the context
CXMLAutoPtr ptrContext((const char*) xmlGetProp( cur, (xmlChar*)"context" ));
string context = (const char*)ptrContext?(const char*)ptrContext:"";
// Add the action
CCombo combo;
combo.init(key, (TKeyButton)((shift?shiftKeyButton:noKeyButton)|(ctrl?ctrlKeyButton:noKeyButton)|(menu?altKeyButton:noKeyButton)));
::CAction::CName actionName ((const char*)ptrAction, ptrParams?(const char*)ptrParams:"");
// Get the actions context manager
CActionsManager *actionManager = ActionsContext.getActionsManager(context);
if (actionManager)
{
bool canAdd= true;
// for keys.xml, don't replace already defined keys
if(getDefine("key_def_no_replace")=="1")
{
// if this combo key is already used for any action,
// or if this action is already bound to any key
if(isNA || actionManager->isComboAssociated(combo) || actionManager->isActionAssociated(actionName))
// don't replace
canAdd= false;
}
// add/replace the combo?
if(canAdd)
{
actionManager->addCombo(actionName, combo);
::CAction *action = actionManager->getAction(actionName);
if (action && repeat) action->Repeat = true;
}
// if the action is to be shown in the Key interface
if(getDefine("key_def_force_display")=="1")
actionManager->forceDisplayForAction(actionName, true);
}
// Done
ret = true;
}
else
{
// todo hulud interface syntax error
nlwarning("<CInterfaceParser::parseKey> No action for key : %s", (const char*)ptrKey);
}
}
else
{
// todo hulud interface syntax error
nlwarning("<CInterfaceParser::parseKey> Unknown key : %s", (const char*)ptrKey);
}
}
else
{
// todo hulud interface syntax error
nlwarning("<CInterfaceParser::parseKey> No name for a key");
}
return ret;
}
//==================================================================
bool CInterfaceParser::parseCommand(xmlNodePtr cur)
{
H_AUTO(parseCommand)
// Parse the key
bool ret = false;
// Localized string
CXMLAutoPtr ptrName((const char*) xmlGetProp( cur, (xmlChar*)"name" ));
if (ptrName)
{
// Does the action exist ?
string name = ptrName;
if (!ICommand::exists (name) || (CUserCommand::CommandMap.find(name) != CUserCommand::CommandMap.end()))
{
// Get the action
CXMLAutoPtr ptrAction((const char*) xmlGetProp( cur, (xmlChar*)"action" ));
if (ptrAction)
{
// Get the params
CXMLAutoPtr ptrParams((const char*) xmlGetProp( cur, (xmlChar*)"params" ));
if (ptrParams)
{
CUserCommand::createCommand (ptrName, ptrAction, ptrParams);
// if prop "ctrlchar" is declared with false, then disable ctrlchar for this command
CXMLAutoPtr prop((const char*) xmlGetProp( cur, (xmlChar*)"ctrlchar" ));
if( (const char*)prop && (CInterfaceElement::convertBool((const char*)prop)==false) )
ICommand::enableControlCharForCommand(ptrName, false);
// Done
ret = true;
}
}
else
{
// todo hulud interface syntax error
nlwarning("<CInterfaceParser::parseCommand> No action for command : %s", (const char*)ptrName);
}
}
}
else
{
// todo hulud interface syntax error
nlwarning("<CInterfaceParser::parseCommand> No name for a key");
}
return ret;
}
//==================================================================
bool CInterfaceParser::parseMacro(xmlNodePtr cur)
{
H_AUTO(parseMacro)
CMacroCmd cmd;
if (cmd.readFrom(cur))
CMacroCmdManager::getInstance()->addMacro(cmd);
else
return false;
return true;
}
//================================================================== //==================================================================
void CInterfaceParser::freeXMLNodeAndSibblings(xmlNodePtr node) void CInterfaceParser::freeXMLNodeAndSibblings(xmlNodePtr node)
{ {
@ -3219,25 +2730,6 @@ bool CInterfaceParser::parseStyle(xmlNodePtr cur)
return true; return true;
} }
// ***************************************************************************
bool CInterfaceParser::parseDDX (xmlNodePtr cur, CInterfaceGroup * parentGroup)
{
H_AUTO(parseDDX )
CInterfaceDDX *pDDX = NULL;
pDDX = new CInterfaceDDX;
if (pDDX)
{
if (!pDDX->parse(cur,parentGroup))
{
delete pDDX;
return false;
}
return true;
}
return false;
}
// *************************************************************************** // ***************************************************************************
bool CInterfaceParser::parseLUAScript (xmlNodePtr cur) bool CInterfaceParser::parseLUAScript (xmlNodePtr cur)
{ {

View file

@ -55,6 +55,40 @@ class CInterfaceParser : public IParser
{ {
public: public:
class IParserModule
{
public:
enum ParsingStage
{
None = 0,
Unresolved = 1,
Resolved = 2,
GroupChildren = 4
};
IParserModule(){
parser = NULL;
parsingStage = None;
}
virtual ~IParserModule(){}
bool canParseInStage( ParsingStage stage )
{
if( ( parsingStage & static_cast< uint >( stage ) ) != 0 )
return true;
else
return false;
}
virtual bool parse( xmlNodePtr cur, CInterfaceGroup *parentGroup ) = 0;
void setParser( CInterfaceParser *p ){ parser = p; }
protected:
CInterfaceParser *parser;
uint parsingStage;
};
CInterfaceParser(); CInterfaceParser();
virtual ~CInterfaceParser(); virtual ~CInterfaceParser();
@ -87,17 +121,15 @@ public:
bool parseProcedure(xmlNodePtr cur, bool reload); bool parseProcedure(xmlNodePtr cur, bool reload);
bool parseSheetSelection(xmlNodePtr cur); bool parseSheetSelection(xmlNodePtr cur);
bool parseAnim(xmlNodePtr cur, CInterfaceGroup * parentGroup); bool parseAnim(xmlNodePtr cur, CInterfaceGroup * parentGroup);
bool parseScene3D (xmlNodePtr cur, CInterfaceGroup * parentGroup);
bool parseActionCategory (xmlNodePtr cur);
bool parseKey(xmlNodePtr cur);
bool parseMacro(xmlNodePtr cur);
bool parseCommand(xmlNodePtr cur);
bool parseStyle(xmlNodePtr cur); bool parseStyle(xmlNodePtr cur);
bool parseDDX (xmlNodePtr cur, CInterfaceGroup * parentGroup);
bool parseLUAScript (xmlNodePtr cur); bool parseLUAScript (xmlNodePtr cur);
bool setupTree (xmlNodePtr cur, CWidgetManager::SMasterGroup *parentGroup); bool setupTree (xmlNodePtr cur, CWidgetManager::SMasterGroup *parentGroup);
bool setupTreeNode (xmlNodePtr cur, CGroupContainer *parentGroup); bool setupTreeNode (xmlNodePtr cur, CGroupContainer *parentGroup);
void addModule( std::string name, IParserModule *module );
IParserModule* getModuleFor( std::string name ) const;
void removeAllModules();
// Called by each parse in parseXMLDocument // Called by each parse in parseXMLDocument
bool solveDefine(xmlNodePtr cur); bool solveDefine(xmlNodePtr cur);
bool solveStyle(xmlNodePtr cur); bool solveStyle(xmlNodePtr cur);
@ -197,6 +229,8 @@ public:
// return false if procedure not found, or if bad action index. return false if has some param variable (@0...) // return false if procedure not found, or if bad action index. return false if has some param variable (@0...)
bool getProcedureAction( const std::string &procName, uint actionIndex, std::string &ah, std::string &params ) const; bool getProcedureAction( const std::string &procName, uint actionIndex, std::string &ah, std::string &params ) const;
void setCacheUIParsing( bool b ){ cacheUIParsing = b; }
protected: protected:
/** /**
@ -305,6 +339,7 @@ protected:
TStyleMap _StyleMap; TStyleMap _StyleMap;
protected: protected:
std::map< std::string, IParserModule* > moduleMap;
// LUA // LUA
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// LUA Interface State. NB: The LUA environnement is not shared between Login/OutGame/InGame // LUA Interface State. NB: The LUA environnement is not shared between Login/OutGame/InGame
@ -315,6 +350,7 @@ protected:
std::set<std::string> _LuaFileScripts; std::set<std::string> _LuaFileScripts;
// Load A .lua. false if parse error. string 'error' contains the eventual error desc (but warning still displayed) // Load A .lua. false if parse error. string 'error' contains the eventual error desc (but warning still displayed)
bool loadLUA(const std::string &luaFile, std::string &error); bool loadLUA(const std::string &luaFile, std::string &error);
bool cacheUIParsing;
}; };
#endif // RZ_INTERFACE_PARSER_H #endif // RZ_INTERFACE_PARSER_H

View file

@ -0,0 +1,526 @@
// 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 "parser_modules.h"
#include "nel/gui/view_text.h"
#include "nel/gui/interface_group.h"
#include "nel/gui/group_list.h"
#include "interface_ddx.h"
#include "macrocmd_manager.h"
#include "../commands.h"
#include "interface_3d_scene.h"
#include "nel/misc/i_xml.h"
using namespace NLMISC;
CIF3DSceneParser::CIF3DSceneParser()
{
parsingStage |= ( Resolved | GroupChildren );
}
CIF3DSceneParser::~CIF3DSceneParser()
{
}
bool CIF3DSceneParser::parse( xmlNodePtr cur, NLGUI::CInterfaceGroup *parentGroup )
{
CInterface3DScene *pScene;
CXMLAutoPtr ptr;
pScene = new CInterface3DScene(CViewBase::TCtorParam());
// parse the group attributes
if (!pScene->parse(cur,parentGroup))
{
delete pScene;
// todo hulud interface syntax error
nlinfo ("cannot parse 3d scene attributes");
return false;
}
if (parentGroup)
{
CGroupList *pList = dynamic_cast<CGroupList*>(parentGroup);
if (pList != NULL)
pList->addChild (pScene);
else
parentGroup->addGroup (pScene);
}
else
{
std::string tmp = "no parent for "+pScene->getId();
// todo hulud interface syntax error
nlinfo (tmp.c_str());
delete pScene;
return false;
}
return true;
}
CIFDDXParser::CIFDDXParser()
{
parsingStage |= ( Resolved | GroupChildren );
}
CIFDDXParser::~CIFDDXParser()
{
}
bool CIFDDXParser::parse( xmlNodePtr cur, NLGUI::CInterfaceGroup *parentGroup )
{
CInterfaceDDX *pDDX = NULL;
pDDX = new CInterfaceDDX;
if (pDDX)
{
if (!pDDX->parse(cur,parentGroup))
{
delete pDDX;
return false;
}
return true;
}
return false;
}
CActionCategoryParser::CActionCategoryParser()
{
parsingStage |= Unresolved;
}
CActionCategoryParser::~CActionCategoryParser()
{
}
bool CActionCategoryParser::parse( xmlNodePtr cur, NLGUI::CInterfaceGroup *parentGroup )
{
// The category
CCategory category;
// Name
CXMLAutoPtr ptr((const char*) xmlGetProp( cur, (xmlChar*)"name" ));
if (ptr)
category.Name = (const char*)ptr;
// Localized string
ptr = (char*) xmlGetProp( cur, (xmlChar*)"hardtext" );
if (ptr)
category.LocalizedName = (const char*)ptr;
// macroisable (per category)
ptr = (char*) xmlGetProp( cur, (xmlChar*)"macroisable" );
if (ptr)
category.Macroisable= CInterfaceElement::convertBool(ptr);
// Count number of action
uint ns = CIXml::countChildren(cur, "action");
category.BaseActions.resize( ns );
std::string actionCategoryContext = "game";
ptr = (char*) xmlGetProp( cur, (xmlChar*)"contexts" );
if (ptr)
actionCategoryContext = (const char *) ptr;
uint actionIndex = 0;
xmlNodePtr actionNode = CIXml::getFirstChildNode(cur, "action");
if (actionNode)
{
do
{
// The action
CBaseAction &action = category.BaseActions[actionIndex];
// list of contexts in which this action is valid
ptr = (char*) xmlGetProp( actionNode, (xmlChar*)"contexts" );
if (ptr)
action.Contexts = (const char *) ptr;
else
action.Contexts = actionCategoryContext; // inherit from action category
// Repeat flag
ptr = (char*) xmlGetProp( actionNode, (xmlChar*)"repeat" );
if (ptr)
fromString((const char*)ptr, action.Repeat);
// KeyDown flag
ptr = (char*) xmlGetProp( actionNode, (xmlChar*)"keydown" );
if (ptr)
fromString((const char*)ptr, action.KeyDown);
// KeyUp flag
ptr = (char*) xmlGetProp( actionNode, (xmlChar*)"keyup" );
if (ptr)
fromString((const char*)ptr, action.KeyUp);
// WaitForServer flag (wait an answer from server before continuing)
ptr = (char*) xmlGetProp( actionNode, (xmlChar*)"waitforserver" );
if (ptr)
fromString((const char*)ptr, action.WaitForServer);
// Action name
ptr = (char*) xmlGetProp( actionNode, (xmlChar*)"name" );
if (ptr)
action.Name = (const char*)ptr;
// Action localized name
ptr = (char*) xmlGetProp( actionNode, (xmlChar*)"hardtext" );
if (ptr)
action.LocalizedName = (const char*)ptr;
// macroisable (per action)
action.Macroisable= true;
ptr = (char*) xmlGetProp( actionNode, (xmlChar*)"macroisable" );
if (ptr)
action.Macroisable = CInterfaceElement::convertBool(ptr);
// Read the parameters
action.Parameters.resize (CIXml::countChildren(actionNode, "parameter"));
uint parameterIndex = 0;
xmlNodePtr paramNode = CIXml::getFirstChildNode(actionNode, "parameter");
if (paramNode)
{
do
{
// The parameter
CBaseAction::CParameter &parameter = action.Parameters[parameterIndex];
// Parameter type
ptr = (char*) xmlGetProp( paramNode, (xmlChar*)"type" );
if (ptr)
{
sint32 tType;
fromString((const char*)ptr, tType);
parameter.Type = (CBaseAction::CParameter::TType)tType;
}
// Parameter name
ptr = (char*) xmlGetProp( paramNode, (xmlChar*)"name" );
if (ptr)
parameter.Name = (const char*)ptr;
// Parameter localized name
ptr = (char*) xmlGetProp( paramNode, (xmlChar*)"hardtext" );
if (ptr)
parameter.LocalizedName = (const char*)ptr;
// Default value
ptr = (char*) xmlGetProp( paramNode, (xmlChar*)"value" );
if (ptr)
parameter.DefaultValue = (const char*)ptr;
// Visible flag
//ptr = (char*) xmlGetProp( paramNode, (xmlChar*)"visible" );
//if (ptr)
// fromString((const char*)ptr, parameter.Visible);
// Parse instance
xmlNodePtr instanceNode = CIXml::getFirstChildNode(paramNode, "instance");
if (instanceNode)
{
do
{
if (!parser->parseInstance(instanceNode))
{
// todo hulud interface syntax error
nlwarning("<CInterfaceParser::parseActionCategory> cannot create instance from template");
}
}
while((instanceNode = CIXml::getNextChildNode(instanceNode, "instance")));
}
parameter.Values.resize (CIXml::countChildren(paramNode, "value"));
uint valueIndex = 0;
xmlNodePtr valueNode = CIXml::getFirstChildNode(paramNode, "value");
if (valueNode)
{
do
{
// The value
CBaseAction::CParameter::CValue &value = parameter.Values[valueIndex];
// Value
ptr = (char*) xmlGetProp( valueNode, (xmlChar*)"value" );
if (ptr)
value.Value = (const char*)ptr;
// list of contexts in which this value is valid
ptr = (char*) xmlGetProp( valueNode, (xmlChar*)"contexts" );
if (ptr) value.Contexts = (const char*) ptr;
else value.Contexts = action.Contexts; // inherit context from action
// Localized value
ptr = (char*) xmlGetProp( valueNode, (xmlChar*)"hardtext" );
if (ptr)
value.LocalizedValue = (const char*)ptr;
valueIndex++;
}
while((valueNode = CIXml::getNextChildNode(valueNode, "value")));
}
parameterIndex++;
}
while((paramNode = CIXml::getNextChildNode(paramNode, "parameter")));
}
// Next action
actionIndex++;
}
while((actionNode = CIXml::getNextChildNode(actionNode, "action")));
}
// Add this category to the action manager
CActionsManager *actionManager = ActionsContext.getActionsManager (category.Name);
if (actionManager)
{
// They want to display debug shortcut in final version
#if FINAL_VERSION
if ((category.Name != "debug") || ClientCfg.AllowDebugCommands)
#else // FINAL_VERSION
if (1)
#endif // FINAL_VERSION
{
actionManager->removeCategory (category.Name);
actionManager->addCategory (category);
}
else
{
// Remove thoses actions from the manager
CAHManager *pAHFM = CAHManager::getInstance();
uint i;
for (i=0; i<category.BaseActions.size(); i++)
{
CAHManager::TFactoryMap::iterator ite = pAHFM->FactoryMap.find (category.BaseActions[i].Name);
if (ite != pAHFM->FactoryMap.end())
{
IActionHandler *ah = ite->second;
pAHFM->FactoryMap.erase (ite);
pAHFM->NameMap.erase (ah);
}
}
}
}
return true;
}
CCommandParser::CCommandParser()
{
parsingStage |= Unresolved;
}
CCommandParser::~CCommandParser()
{
}
bool CCommandParser::parse( xmlNodePtr cur, NLGUI::CInterfaceGroup *parentGroup )
{
// Parse the key
bool ret = false;
// Localized string
CXMLAutoPtr ptrName((const char*) xmlGetProp( cur, (xmlChar*)"name" ));
if (ptrName)
{
// Does the action exist ?
std::string name = ptrName;
if (!ICommand::exists (name) || (CUserCommand::CommandMap.find(name) != CUserCommand::CommandMap.end()))
{
// Get the action
CXMLAutoPtr ptrAction((const char*) xmlGetProp( cur, (xmlChar*)"action" ));
if (ptrAction)
{
// Get the params
CXMLAutoPtr ptrParams((const char*) xmlGetProp( cur, (xmlChar*)"params" ));
if (ptrParams)
{
CUserCommand::createCommand (ptrName, ptrAction, ptrParams);
// if prop "ctrlchar" is declared with false, then disable ctrlchar for this command
CXMLAutoPtr prop((const char*) xmlGetProp( cur, (xmlChar*)"ctrlchar" ));
if( (const char*)prop && (CInterfaceElement::convertBool((const char*)prop)==false) )
ICommand::enableControlCharForCommand(ptrName, false);
// Done
ret = true;
}
}
else
{
// todo hulud interface syntax error
nlwarning("<CInterfaceParser::parseCommand> No action for command : %s", (const char*)ptrName);
}
}
}
else
{
// todo hulud interface syntax error
nlwarning("<CInterfaceParser::parseCommand> No name for a key");
}
return ret;
}
CKeyParser::CKeyParser()
{
parsingStage |= Unresolved;
}
CKeyParser::~CKeyParser()
{
}
bool CKeyParser::parse( xmlNodePtr cur, NLGUI::CInterfaceGroup *parentGroup )
{
// Parse the key
bool ret = false;
// Localized string
TKey key;
CXMLAutoPtr ptrKey((const char*) xmlGetProp( cur, (xmlChar*)"name" ));
if (ptrKey)
{
bool isNA = std::string((const char*)ptrKey) == std::string("N/A");
// Get the key from the string
key = CEventKey::getKeyFromString ((const char*)ptrKey);
if (key != KeyCount || isNA)
{
// Get the action
CXMLAutoPtr ptrAction((const char*) xmlGetProp( cur, (xmlChar*)"action" ));
if (ptrAction)
{
// Get the params
CXMLAutoPtr ptrParams((const char*) xmlGetProp( cur, (xmlChar*)"params" ));
// Get the modifiers
bool shift=false;
bool ctrl=false;
bool menu=false;
CXMLAutoPtr ptr((const char*) xmlGetProp( cur, (xmlChar*)"shift" ));
if (ptr)
fromString((const char*)ptr, shift);
ptr = (char*) xmlGetProp( cur, (xmlChar*)"ctrl" );
if (ptr)
fromString((const char*)ptr, ctrl);
ptr = (char*) xmlGetProp( cur, (xmlChar*)"menu" );
if (ptr)
fromString((const char*)ptr, menu);
// Repeat flag
bool repeat=false;
ptr = (char*) xmlGetProp( cur, (xmlChar*)"repeat" );
if (ptr)
fromString((const char*)ptr, repeat);
// Get the context
CXMLAutoPtr ptrContext((const char*) xmlGetProp( cur, (xmlChar*)"context" ));
std::string context = (const char*)ptrContext?(const char*)ptrContext:"";
// Add the action
CCombo combo;
combo.init(key, (TKeyButton)((shift?shiftKeyButton:noKeyButton)|(ctrl?ctrlKeyButton:noKeyButton)|(menu?altKeyButton:noKeyButton)));
::CAction::CName actionName ((const char*)ptrAction, ptrParams?(const char*)ptrParams:"");
// Get the actions context manager
CActionsManager *actionManager = ActionsContext.getActionsManager(context);
if (actionManager)
{
bool canAdd= true;
// for keys.xml, don't replace already defined keys
if( parser->getDefine("key_def_no_replace")=="1" )
{
// if this combo key is already used for any action,
// or if this action is already bound to any key
if(isNA || actionManager->isComboAssociated(combo) || actionManager->isActionAssociated(actionName))
// don't replace
canAdd= false;
}
// add/replace the combo?
if(canAdd)
{
actionManager->addCombo(actionName, combo);
::CAction *action = actionManager->getAction(actionName);
if (action && repeat) action->Repeat = true;
}
// if the action is to be shown in the Key interface
if( parser->getDefine("key_def_force_display")=="1" )
actionManager->forceDisplayForAction(actionName, true);
}
// Done
ret = true;
}
else
{
// todo hulud interface syntax error
nlwarning("<CInterfaceParser::parseKey> No action for key : %s", (const char*)ptrKey);
}
}
else
{
// todo hulud interface syntax error
nlwarning("<CInterfaceParser::parseKey> Unknown key : %s", (const char*)ptrKey);
}
}
else
{
// todo hulud interface syntax error
nlwarning("<CInterfaceParser::parseKey> No name for a key");
}
return ret;
}
CMacroParser::CMacroParser()
{
parsingStage |= Unresolved;
}
CMacroParser::~CMacroParser()
{
}
bool CMacroParser::parse( xmlNodePtr cur, NLGUI::CInterfaceGroup *parentGroup )
{
H_AUTO(parseMacro)
CMacroCmd cmd;
if (cmd.readFrom(cur))
CMacroCmdManager::getInstance()->addMacro(cmd);
else
return false;
return true;
}

View file

@ -0,0 +1,77 @@
// 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 PARSER_MODULES_H
#define PARSER_MODULES_H
#include "interface_parser.h"
class CIF3DSceneParser : public CInterfaceParser::IParserModule
{
public:
CIF3DSceneParser();
~CIF3DSceneParser();
bool parse( xmlNodePtr cur, CInterfaceGroup *parentGroup );
};
class CIFDDXParser : public CInterfaceParser::IParserModule
{
public:
CIFDDXParser();
~CIFDDXParser();
bool parse( xmlNodePtr cur, CInterfaceGroup *parentGroup );
};
class CActionCategoryParser : public CInterfaceParser::IParserModule
{
public:
CActionCategoryParser();
~CActionCategoryParser();
bool parse( xmlNodePtr cur, CInterfaceGroup *parentGroup );
};
class CCommandParser : public CInterfaceParser::IParserModule
{
public:
CCommandParser();
~CCommandParser();
bool parse( xmlNodePtr cur, CInterfaceGroup *parentGroup );
};
class CKeyParser : public CInterfaceParser::IParserModule
{
public:
CKeyParser();
~CKeyParser();
bool parse( xmlNodePtr cur, CInterfaceGroup *parentGroup );
};
class CMacroParser : public CInterfaceParser::IParserModule
{
public:
CMacroParser();
~CMacroParser();
bool parse( xmlNodePtr cur, CInterfaceGroup *parentGroup );
};
#endif