#ifndef FACTORY_H_SEEN #define FACTORY_H_SEEN #include #include #include /** * A simple singleton implementation. */ template struct Singleton { static T& instance() { static T inst; return inst; } }; namespace FactoryExceptions { class TypeNotRegistered : public std::exception { public: TypeNotRegistered(const std::string& typeString) : std::exception(), typeString(typeString) { } virtual ~TypeNotRegistered() throw() { } const char* what() const throw() { return typeString.c_str(); } private: const std::string typeString; }; } /** * A Factory for creating objects which can be identified by strings. */ template class Factory { public: typedef BaseObject* CreateFunction(); bool registerObject(const std::string& id, CreateFunction* createFunction) { return this->objectMap.insert(std::make_pair(id, createFunction)).second; } BaseObject* createObject(const std::string& id) const throw(FactoryExceptions::TypeNotRegistered) { typename std::map::const_iterator it = this->objectMap.find(id); if (it == this->objectMap.end()) { throw FactoryExceptions::TypeNotRegistered(id); } return it->second(); } private: std::map objectMap; }; #include "xml/node.h" struct NodeTraits { static std::string getTypeString(const Inkscape::XML::Node& node) { std::string name; switch (node.type()) { case Inkscape::XML::TEXT_NODE: name = "string"; break; case Inkscape::XML::ELEMENT_NODE: { gchar const* const sptype = node.attribute("sodipodi:type"); if (sptype) { name = sptype; } else { name = node.name(); } break; } default: name = ""; break; } return name; } }; #endif