diff --git a/code/ryzom/client/src/actions.cpp b/code/ryzom/client/src/actions.cpp index 599f7a637..9052455d8 100644 --- a/code/ryzom/client/src/actions.cpp +++ b/code/ryzom/client/src/actions.cpp @@ -747,11 +747,20 @@ const CActionsManager::CCategoryLocator *CActionsManager::getActionLocator (cons while ((ite != _ActionCategory.end ()) && (ite->first == name.Name)) { // 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 uint i; - for (i=0; idriver = driver; this->textcontext = textcontext; diff --git a/code/ryzom/client/src/interface_v3/interface_parser.cpp b/code/ryzom/client/src/interface_v3/interface_parser.cpp index 195a70118..76d378963 100644 --- a/code/ryzom/client/src/interface_v3/interface_parser.cpp +++ b/code/ryzom/client/src/interface_v3/interface_parser.cpp @@ -34,11 +34,8 @@ #include "nel/gui/lua_ihm.h" #include "nel/gui/lua_manager.h" -#include "interface_3d_scene.h" #include "lua_ihm_ryzom.h" -#include "interface_ddx.h" -#include "macrocmd_manager.h" -#include "../commands.h" + #ifdef LUA_NEVRAX_VERSION #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 NLGUI; +using namespace std; 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 // ---------------------------------------------------------------------------- @@ -212,11 +199,13 @@ CInterfaceParser::CInterfaceParser() { // LUA _LuaState= NULL; + cacheUIParsing = false; } CInterfaceParser::~CInterfaceParser() { _LuaState = NULL; + removeAllModules(); } /** Convert a string into a memstream */ @@ -328,7 +317,7 @@ bool CInterfaceParser::parseInterface (const std::vector & strings, xmlNodePtr cur = NULL; bool saveParseResult = false; bool readFromUncompressedXML = true; - if( false /* isFilename && ClientCfg.CacheUIParsing */ ) + if( isFilename && cacheUIParsing ) { saveParseResult = true; std::string archive = CPath::lookup(nextFileName + "_compressed", false, false); @@ -457,11 +446,6 @@ bool CInterfaceParser::parseXMLDocument(xmlNodePtr root, bool reload) //parse templates 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(); while (curNode) @@ -515,30 +499,20 @@ bool CInterfaceParser::parseXMLDocument(xmlNodePtr root, bool reload) // todo hulud interface syntax error 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") ) { if (!parseStyle(curNode)) // todo hulud interface syntax error 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; } @@ -647,18 +621,6 @@ bool CInterfaceParser::parseXMLDocument(xmlNodePtr root, bool reload) // todo hulud interface syntax error 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") ) { if(!parseLUAScript(root)) @@ -667,6 +629,15 @@ bool CInterfaceParser::parseXMLDocument(xmlNodePtr root, bool reload) 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; } @@ -860,78 +831,6 @@ bool CInterfaceParser::parseInstance(xmlNodePtr cur) 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::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::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) { @@ -1349,10 +1248,15 @@ bool CInterfaceParser::parseGroupChildren(xmlNodePtr cur, CInterfaceGroup * pare ok = ok && parseVector(cur); else if ( !strcmp((char*)cur->name,"link") ) ok = ok && parseLink(cur,parentGroup); - else if ( !strcmp((char*)cur->name,"scene3d") ) - ok = ok && parseScene3D(cur,parentGroup); - else if ( !strcmp((char*)cur->name,"ddx") ) - ok = ok && parseDDX(cur,parentGroup); + else + { + IParserModule *module = getModuleFor( (char*)( cur->name ) ); + if( module != NULL ) + { + if( module->canParseInStage( IParserModule::GroupChildren ) ) + ok = ok && module->parse( cur, parentGroup ); + } + } cur = cur->next; @@ -1610,6 +1514,42 @@ bool CInterfaceParser::setupTreeNode (xmlNodePtr cur, CGroupContainer * /* paren 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 */) { @@ -2471,435 +2411,6 @@ bool CInterfaceParser::parseAnim(xmlNodePtr cur, CInterfaceGroup * parentGroup) 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(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 ¶meter = 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(" 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; iFactoryMap.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(" No action for key : %s", (const char*)ptrKey); - } - } - else - { - // todo hulud interface syntax error - nlwarning(" Unknown key : %s", (const char*)ptrKey); - } - } - else - { - // todo hulud interface syntax error - nlwarning(" 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(" No action for command : %s", (const char*)ptrName); - } - } - } - else - { - // todo hulud interface syntax error - nlwarning(" 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) { @@ -3219,25 +2730,6 @@ bool CInterfaceParser::parseStyle(xmlNodePtr cur) 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) { diff --git a/code/ryzom/client/src/interface_v3/interface_parser.h b/code/ryzom/client/src/interface_v3/interface_parser.h index 3b1bd4e4b..c78d87577 100644 --- a/code/ryzom/client/src/interface_v3/interface_parser.h +++ b/code/ryzom/client/src/interface_v3/interface_parser.h @@ -55,6 +55,40 @@ class CInterfaceParser : public IParser { 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(); virtual ~CInterfaceParser(); @@ -87,16 +121,14 @@ public: bool parseProcedure(xmlNodePtr cur, bool reload); bool parseSheetSelection(xmlNodePtr cur); 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 parseDDX (xmlNodePtr cur, CInterfaceGroup * parentGroup); bool parseLUAScript (xmlNodePtr cur); bool setupTree (xmlNodePtr cur, CWidgetManager::SMasterGroup *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 bool solveDefine(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...) bool getProcedureAction( const std::string &procName, uint actionIndex, std::string &ah, std::string ¶ms ) const; + void setCacheUIParsing( bool b ){ cacheUIParsing = b; } + protected: /** @@ -305,6 +339,7 @@ protected: TStyleMap _StyleMap; protected: + std::map< std::string, IParserModule* > moduleMap; // LUA // ---------------------------------------------------------------------------------- // LUA Interface State. NB: The LUA environnement is not shared between Login/OutGame/InGame @@ -315,6 +350,7 @@ protected: std::set _LuaFileScripts; // 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 cacheUIParsing; }; #endif // RZ_INTERFACE_PARSER_H diff --git a/code/ryzom/client/src/interface_v3/parser_modules.cpp b/code/ryzom/client/src/interface_v3/parser_modules.cpp new file mode 100644 index 000000000..9d912bd77 --- /dev/null +++ b/code/ryzom/client/src/interface_v3/parser_modules.cpp @@ -0,0 +1,526 @@ +// Ryzom - MMORPG Framework +// 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 . + +#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(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 ¶meter = 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(" 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; iFactoryMap.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(" No action for command : %s", (const char*)ptrName); + } + } + } + else + { + // todo hulud interface syntax error + nlwarning(" 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(" No action for key : %s", (const char*)ptrKey); + } + } + else + { + // todo hulud interface syntax error + nlwarning(" Unknown key : %s", (const char*)ptrKey); + } + } + else + { + // todo hulud interface syntax error + nlwarning(" 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; +} + diff --git a/code/ryzom/client/src/interface_v3/parser_modules.h b/code/ryzom/client/src/interface_v3/parser_modules.h new file mode 100644 index 000000000..375fccb9d --- /dev/null +++ b/code/ryzom/client/src/interface_v3/parser_modules.h @@ -0,0 +1,77 @@ +// Ryzom - MMORPG Framework +// 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 . + + +#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