summaryrefslogtreecommitdiffstats
path: root/src/factory.h
blob: 495db54742c9683b540bef28931b592c625a4da1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#pragma once

#include <exception>
#include <map>
#include <string>

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 BaseObject>
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 std::string, CreateFunction*>::const_iterator it = this->objectMap.find(id);

		if (it == this->objectMap.end()) {
			throw FactoryExceptions::TypeNotRegistered(id);
		}

		return it->second();
	}

private:
	std::map<const std::string, CreateFunction*> 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;
	}
};