1 /* 2 Copyright (C) 2005 Matthias Braun <matze@braunis.de> 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (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 General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 */ 18 19 /** 20 * @author Matthias Braun 21 * @file ComponentFactory.hpp 22 */ 23 24 #ifndef __COMPONENT_FACTORY_HPP__ 25 #define __COMPONENT_FACTORY_HPP__ 26 27 #include <map> 28 #include <string> 29 #include <memory> 30 31 const char * GUI_TRANSLATE(const char * msgid); 32 std::string GUI_TRANSLATE(const std::string& msgid); 33 34 class Component; 35 class XmlReader; 36 37 /** 38 * @class Factory 39 */ 40 class Factory 41 { 42 public: ~Factory()43 virtual ~Factory() 44 { } 45 46 virtual Component* createComponent(XmlReader& reader) = 0; 47 }; 48 49 typedef std::map<std::string, Factory*> ComponentFactories; 50 extern ComponentFactories* component_factories; 51 52 /** 53 * @note From Matze: 54 * Yes I know macros are evil, but in this specific case they save 55 * A LOT of typing and evil code duplication. 56 * I'll happily accept alternatives if someone can present me one that does 57 * not involve typing 4 or more lines for each object class 58 */ 59 #define DECLARE_COMPONENT_FACTORY(CLASS) \ 60 class INTERN_##CLASS##Factory : public Factory \ 61 { \ 62 public: \ 63 INTERN_##CLASS##Factory() \ 64 { \ 65 if(component_factories == 0) \ 66 component_factories = new ComponentFactories; \ 67 \ 68 component_factories->insert(std::make_pair(#CLASS, this)); \ 69 } \ 70 \ 71 virtual Component* createComponent(XmlReader& reader) \ 72 { \ 73 std::auto_ptr<CLASS> component (new CLASS()); \ 74 component->parse(reader); \ 75 return component.release(); \ 76 } \ 77 }; 78 #define IMPLEMENT_COMPONENT_FACTORY(CLASS) \ 79 DECLARE_COMPONENT_FACTORY(CLASS) \ 80 INTERN_##CLASS##Factory factory_##CLASS; 81 82 #endif 83 84