Resolve "Toggle Free Look with Hotkey"
[ryzomcore.git] / ryzom / server / src / sabrina / s_phrase_factory.h
blob642a26735e541c7b30ca534dd37d9d721a09e9ef
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #ifndef RY_S_PHRASE_FACTORY_H
20 #define RY_S_PHRASE_FACTORY_H
22 #include "nel/misc/types_nl.h"
23 #include "s_phrase.h"
27 /// Macro used to declare a Sabrina phrase class factory with a default implementation
30 #define DEFAULT_SPHRASE_FACTORY(_class_,_type_) \
31 class _class_##Factory : public ISPhraseFactory \
33 public:\
34 _class_##Factory()\
36 init();\
37 for (uint i = 0; i < (*Factories).size(); i++ ){ \
38 if ( (*Factories)[i].first == _type_){nlerror("<ISPhraseFactory buildPhrase> brick type %s is affected to more than one class",BRICK_TYPE::toString(_type_).c_str() );}} \
39 Factories->push_back(std::make_pair(_type_,this));\
40 };\
41 protected:\
42 CSPhrase * buildPhrase( const TDataSetRow & actorRowId, const std::vector< const CStaticBrick* >& bricks )\
44 _class_ *inst = new _class_;\
45 if ( !inst->build( actorRowId, bricks ) ){delete inst;return NULL;} \
46 return inst;\
48 };\
49 _class_##Factory* _class_##FactoryInstance = new _class_##Factory;
53 /// Macro used to declare a Sabrina phrase class factory and implement the build phrase method
54 #define IMPLEMENT_SPHRASE_FACTORY(_class_,_type_) \
55 class _class_##Factory : public ISPhraseFactory\
57 public:\
58 _class_##Factory ()\
60 init();\
61 for (uint i = 0; i < (*Factories).size(); i++ ){ \
62 if ( (*Factories)[i].first == _type_){nlerror("<ISPhraseFactory buildPhrase> brick type %s is affected to more than one class",BRICK_TYPE::toString(_type_) );}} \
63 Factories->push_back(std::make_pair(_type_,this));\
64 };\
65 protected:\
66 CSPhrase * buildPhrase( const TDataSetRow & actorRowId, const std::vector< const CStaticBrick* >& bricks );\
67 }; \
68 _class_##Factory* _class_##FactoryInstance = new _class_##Factory;\
69 CSPhrase * _class_##Factory::buildPhrase( const TDataSetRow & actorRowId, const std::vector< const CStaticBrick* >& bricks )
73 /**
74 * class factory for sabrina phrase
75 * \author Nicolas Brigand
76 * \author Nevrax France
77 * \date 2003
79 class ISPhraseFactory
81 public:
82 /// clear the class factory
83 static void clear();
85 ///\build a phrase from the user row and the bricks composing the phrase
86 inline static CSPhrase * buildPhrase( const TDataSetRow & actorRowId,const std::vector< NLMISC::CSheetId>& brickIds )
88 // the check to see if there is at least a brick is made before
89 nlassert( !brickIds.empty() );
90 nlassert( Factories );
92 // transform sheet ids into forms
93 std::vector< const CStaticBrick* > bricks( brickIds.size() );
94 uint16 nbNull = 0;
95 for ( uint i = 0; i < bricks.size(); ++i )
97 // skip unknown sheetIds
98 if ( brickIds[i] == NLMISC::CSheetId::Unknown )
100 ++nbNull;
101 continue;
104 if( NLMISC::CSheetId::fileExtensionFromType( brickIds[i].getType() ) == std::string("sbrick") )
106 bricks[i-nbNull] = CSheets::getSBrickForm( brickIds[i] );
108 else if( NLMISC::CSheetId::fileExtensionFromType( brickIds[i].getType() ) == std::string("item") )
110 bricks[i-nbNull] = (const CStaticBrick*) CSheets::getForm( brickIds[i] );
113 if ( bricks[i-nbNull] == NULL )
115 nlwarning( "<ISPhraseFactory buildPhrase> invalid SBrick sheet %u, named %s",brickIds[i].asInt(),brickIds[i].toString().c_str() );
116 return NULL;
120 if (nbNull)
121 bricks.resize( bricks.size() - nbNull);
123 //get the root brick family and the associated factory
124 for ( uint i = 0; i < Factories->size(); i++ )
126 if ( (*Factories)[i].first == BRICK_FAMILIES::brickType(bricks[0]->Family) )
128 return (*Factories)[i].second->buildPhrase( actorRowId, bricks);
131 nlwarning( "<ISPhraseFactory buildPhrase> the brick type %s has no corresponding phrase class", BRICK_TYPE::toString(BRICK_FAMILIES::brickType( bricks[0]->Family )).c_str() );
132 return NULL;
135 /// init the factory
136 static void init()
138 if ( Factories == NULL )
139 Factories = new std::vector< std::pair< BRICK_TYPE::EBrickType, ISPhraseFactory* > >;
142 protected:
145 * Create a step from parameters
146 * \param params : a vector of vector of strings describing the step params
147 * \return a pointer on the built step (NULL if failure)
149 virtual CSPhrase * buildPhrase( const TDataSetRow & actorRowId, const std::vector< const CStaticBrick* >& brickIds ) = 0;
151 ///the phrase factories. We use a pointer here because we cant control the order in which ctor of static members are called
152 static std::vector< std::pair< BRICK_TYPE::EBrickType, ISPhraseFactory* > >* Factories;
155 #endif // RY_S_PHRASE_FACTORY_H
157 /* End of s_phrase_factory.h */