// 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 NL_INTERFACE_OBSERVER_H #define NL_INTERFACE_OBSERVER_H #include "nel/misc/types_nl.h" #include "interface_manager.h" #include "nel/misc/xml_auto_ptr.h" /** * interface to define a simple observer * \author Nicolas Brigand * \author Nevrax France * \date 2002 */ class IInterfaceObserver : public NLMISC::ICDBNode::IPropertyObserver { public: /** * parse the element and initalize it * \param cur : pointer to the node describing this element * \param ctrl : pointer to the parent group * \return true if success */ virtual bool parse (xmlNodePtr cur, CInterfaceGroup *parentGroup)=0; /** * observer update */ virtual void update (NLMISC::CCDBNodeLeaf* leaf)=0; }; class IInterfaceObserverFactory; /** * manager for observer factory * \author Nicolas Brigand * \author Nevrax France * \date 2002 */ class CInterfaceObserverFactoryManager { public: typedef std::map< std::string, IInterfaceObserverFactory* > TFactoryMap; static CInterfaceObserverFactoryManager* getInstance() { if (_GlobalInstance == NULL) _GlobalInstance = new CInterfaceObserverFactoryManager; return _GlobalInstance; } /// map of action handler factories TFactoryMap FactoryMap; private: CInterfaceObserverFactoryManager(){} static CInterfaceObserverFactoryManager *_GlobalInstance; }; /** * interface for observer factory * \author Nicolas Brigand * \author Nevrax France * \date 2002 */ class IInterfaceObserverFactory { public: /** * build the desired observer from script *\param idHandler : the string identifying the handler *\return a pointer to the factory instance to be used */ static IInterfaceObserver *create(xmlNodePtr node,CInterfaceGroup* parentGroup) { CInterfaceManager* iMngr = CInterfaceManager::getInstance(); CXMLAutoPtr idObserver((const char*)xmlGetProp(node,(char unsigned*)"action")); if (!idObserver) { nlinfo("action not found in a observer node"); return NULL; } CXMLAutoPtr ptr((const char*) xmlGetProp (node, (xmlChar*)"data")); if (!ptr) { nlinfo ("no data in a observer tag"); return NULL; } IInterfaceObserver* obs =NULL; char * end = ptr.getDatas() + strlen( ptr.getDatas() ); char * dataTok = strtok( ptr.getDatas()," ,"); NLMISC::ICDBNode::CTextId textId; while(dataTok) { std::string data (dataTok); if (NLGUI::CDBManager::getInstance()->getDbProp(data,false) == NULL) // Full path provided ? No. { CInterfaceGroup *parent = parentGroup; while (parent != NULL) { std::string sTmp; if (data[0] == ':') sTmp = parent->getId() + data; else sTmp = parent->getId() + ":" + data; if (NLGUI::CDBManager::getInstance()->getDbProp(sTmp,false) != NULL) { data = sTmp; break; } parent = parent->getParent(); } if (NLGUI::CDBManager::getInstance()->getDbProp(data,false) == NULL) { std::string sTmp = std::string("data (")+std::string(dataTok)+std::string(") in a observer tag do not exist, CREATING!"); nlinfo (sTmp.c_str()); data = (const char*)dataTok; NLGUI::CDBManager::getInstance()->getDbProp (data, true); } } if ( !obs ) { CInterfaceObserverFactoryManager::TFactoryMap::const_iterator it = CInterfaceObserverFactoryManager::getInstance()->FactoryMap.find((const char *) idObserver); if (it== CInterfaceObserverFactoryManager::getInstance()->FactoryMap.end()) { nlinfo("undefined observer : %s", (const char*)idObserver); return NULL; } obs = it->second->createObserver(node,parentGroup); if (!obs) { return NULL; } } textId = NLMISC::ICDBNode::CTextId( data ); if ( ! NLGUI::CDBManager::getInstance()->getDB()->addObserver(obs,textId ) ) { return NULL; } dataTok+= strlen(dataTok ) +1; if (dataTok >= end) break; dataTok = strtok( dataTok," ,"); } return obs; } /** * Create an action handler *\param node : a pointer to the XML node containing the handlers parameters *\return a pointer to the action handler created */ virtual IInterfaceObserver *createObserver(xmlNodePtr node,CInterfaceGroup* parent)=0; }; /** * register a new observer by defining the associated factory and insert the handler name in the global action handler map * \param handler : name of the action handler class * \param name : name of the action handler in the map (same as the "onaction" value in the XML script) */ #define REGISTER_OBSERVER(observer ,name) \ class observer##Factory : public IInterfaceObserverFactory\ {\ public:\ observer##Factory ()\ {\ CInterfaceObserverFactoryManager::getInstance()->FactoryMap.insert(make_pair(std::string(name),this));\ };\ protected:\ IInterfaceObserver *createObserver(xmlNodePtr node,CInterfaceGroup* parent)\ {\ observer * buf = new observer; \ buf->parse(node,parent);\ return buf;\ }\ }; \ observer##Factory observer##FactoryInstance ;\ #endif // NL_INTERFACE_OBSERVER_H /* End of interface_observer.h */