diff options
| author | Markus Engel <markus.engel@tum.de> | 2013-04-07 23:31:41 +0000 |
|---|---|---|
| committer | Markus Engel <markus.engel@tum.de> | 2013-04-07 23:31:41 +0000 |
| commit | e9d86314ef5d8aafc2ec7677fe4825a346276ce4 (patch) | |
| tree | 59ebe8b86e8b25336a336e5d7465aa20435f00ca /src | |
| parent | Merge Object and subclasses. Merging of SP- and C-classes complete. (diff) | |
| download | inkscape-e9d86314ef5d8aafc2ec7677fe4825a346276ce4.tar.gz inkscape-e9d86314ef5d8aafc2ec7677fe4825a346276ce4.zip | |
Added exception to SPFactory / basic handling to SPObject.
(bzr r11608.1.87)
Diffstat (limited to 'src')
| -rw-r--r-- | src/sp-factory.cpp | 40 | ||||
| -rw-r--r-- | src/sp-factory.h | 15 | ||||
| -rw-r--r-- | src/sp-object.cpp | 71 |
3 files changed, 87 insertions, 39 deletions
diff --git a/src/sp-factory.cpp b/src/sp-factory.cpp index 29b308111..272584ca6 100644 --- a/src/sp-factory.cpp +++ b/src/sp-factory.cpp @@ -5,43 +5,53 @@ #include "sp-object.h" #include "xml/node.h" + +SPFactory::TypeNotRegistered::TypeNotRegistered(const std::string& type) + : std::exception(), type(type) { +} + +const char* SPFactory::TypeNotRegistered::what() const noexcept { + return type.c_str(); +} + SPFactory& SPFactory::instance() { static SPFactory factory; return factory; } -bool SPFactory::registerObject(std::string id, std::function<SPObject*()> createFunction) { +bool SPFactory::registerObject(const std::string& id, std::function<SPObject* ()> createFunction) { return this->objectMap.insert(std::make_pair(id, createFunction)).second; + + // replace when gcc supports this + //return this->objectMap.emplace(id, createFunction).second; } SPObject* SPFactory::createObject(const Inkscape::XML::Node& id) const { - std::map<std::string, std::function<SPObject*()>>::const_iterator entry; + std::string name; switch (id.type()) { case Inkscape::XML::TEXT_NODE: - entry = this->objectMap.find("string"); + name = "string"; break; case Inkscape::XML::ELEMENT_NODE: { - gchar const* const type_name = id.attribute("sodipodi:type"); + gchar const* const sptype = id.attribute("sodipodi:type"); - if (type_name) { - entry = this->objectMap.find(type_name); + if (sptype) { + name = sptype; } else { - entry = this->objectMap.find(id.name()); + name = id.name(); } - break; } default: - entry = this->objectMap.end(); + break; } - if (entry == this->objectMap.end()) { - g_warning("Factory: Type \"%s\" not registered!", id.name()); - - return 0; + try { + std::function<SPObject* ()> createFunction = this->objectMap.at(name); + return createFunction(); + } catch (const std::out_of_range& ex) { + std::throw_with_nested(TypeNotRegistered(name)); } - - return (entry->second)(); } diff --git a/src/sp-factory.h b/src/sp-factory.h index c541781df..359ac7acc 100644 --- a/src/sp-factory.h +++ b/src/sp-factory.h @@ -1,5 +1,6 @@ #pragma once +#include <exception> #include <functional> #include <map> #include <string> @@ -17,12 +18,20 @@ namespace Inkscape { */ class SPFactory { public: - static SPFactory& instance(); + class TypeNotRegistered : public std::exception { + public: + TypeNotRegistered(const std::string& type); + const char* what() const noexcept; + + private: + const std::string type; + }; - bool registerObject(std::string id, std::function<SPObject*()> createFunction); + static SPFactory& instance(); + bool registerObject(const std::string& id, std::function<SPObject* ()> createFunction); SPObject* createObject(const Inkscape::XML::Node& id) const; private: - std::map<std::string, std::function<SPObject*()>> objectMap; + std::map<const std::string, std::function<SPObject* ()>> objectMap; }; diff --git a/src/sp-object.cpp b/src/sp-object.cpp index 7d42efebe..ff5426282 100644 --- a/src/sp-object.cpp +++ b/src/sp-object.cpp @@ -209,6 +209,34 @@ public: } + + + + + +#include <stdexcept> +#include <exception> + +void log_exception(std::exception_ptr exception) { + try { + std::rethrow_exception(exception); + } catch (const std::exception& e) { + std::cerr << "Caught Exception of type " << std::string(typeid(e).name()) << '\n'; + std::cerr << "Message: " << std::string(e.what()) << '\n'; + + try { + std::rethrow_if_nested(e); + } catch (...) { + std::cerr << "Inner Exception: \n"; + log_exception(std::current_exception()); + } + } +} + + + + + gchar const* SPObject::getId() const { return id; } @@ -592,22 +620,17 @@ SPObject *SPObject::get_child_by_repr(Inkscape::XML::Node *repr) void SPObject::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) { SPObject* object = this; -// GType type = sp_repr_type_lookup(child); -// if (!type) { -// return; -// } -// SPObject *ochild = SP_OBJECT(g_object_new(type, 0)); - - SPObject* ochild = SPFactory::instance().createObject(*child); - if (!ochild) { - return; - } + try { + SPObject* ochild = SPFactory::instance().createObject(*child); - SPObject *prev = ref ? object->get_child_by_repr(ref) : NULL; - object->attach(ochild, prev); - sp_object_unref(ochild, NULL); + SPObject *prev = ref ? object->get_child_by_repr(ref) : NULL; + object->attach(ochild, prev); + sp_object_unref(ochild, NULL); - ochild->invoke_build(object->document, child, object->cloned); + ochild->invoke_build(object->document, child, object->cloned); + } catch (const SPFactory::TypeNotRegistered& e) { + log_exception(std::current_exception()); + } } void SPObject::release() { @@ -657,14 +680,20 @@ void SPObject::build(SPDocument *document, Inkscape::XML::Node *repr) { // } // SPObject *child = SP_OBJECT(g_object_new(type, 0)); - SPObject* child = SPFactory::instance().createObject(*rchild); - if (!child) { - continue; - } +// SPObject* child = SPFactory::instance().createObject(*rchild); +// if (!child) { +// continue; +// } - object->attach(child, object->lastChild()); - sp_object_unref(child, NULL); - child->invoke_build(document, rchild, object->cloned); + try { + SPObject* child = SPFactory::instance().createObject(*rchild); + + object->attach(child, object->lastChild()); + sp_object_unref(child, NULL); + child->invoke_build(document, rchild, object->cloned); + } catch (const SPFactory::TypeNotRegistered& e) { + log_exception(std::current_exception()); + } } } |
