aboutsummaryrefslogtreecommitdiff
path: root/include/cru/ui/mapper
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-01-17 22:55:09 +0800
committercrupest <crupest@outlook.com>2022-01-17 22:55:09 +0800
commit67dd012c0f49898f1734c46d3bb264f59d056a8e (patch)
tree780dc9c50868a8e7b89e68b463a60745fce72ae9 /include/cru/ui/mapper
parent81f7d5faaaf79149070a901a4f299aee70c46379 (diff)
downloadcru-67dd012c0f49898f1734c46d3bb264f59d056a8e.tar.gz
cru-67dd012c0f49898f1734c46d3bb264f59d056a8e.tar.bz2
cru-67dd012c0f49898f1734c46d3bb264f59d056a8e.zip
...
Diffstat (limited to 'include/cru/ui/mapper')
-rw-r--r--include/cru/ui/mapper/Mapper.hpp82
-rw-r--r--include/cru/ui/mapper/MapperRegistry.hpp26
2 files changed, 108 insertions, 0 deletions
diff --git a/include/cru/ui/mapper/Mapper.hpp b/include/cru/ui/mapper/Mapper.hpp
new file mode 100644
index 00000000..f2d347f1
--- /dev/null
+++ b/include/cru/ui/mapper/Mapper.hpp
@@ -0,0 +1,82 @@
+#pragma once
+
+#include "../Base.hpp"
+
+#include "cru/common/Exception.hpp"
+#include "cru/xml/XmlNode.hpp"
+
+#include <typeindex>
+#include <typeinfo>
+
+namespace cru::ui::mapper {
+template <typename T>
+class Mapper;
+
+class CRU_UI_API MapperBase : public Object {
+ public:
+ explicit MapperBase(std::type_index type_index);
+
+ CRU_DELETE_COPY(MapperBase)
+ CRU_DELETE_MOVE(MapperBase)
+
+ ~MapperBase() override = default;
+
+ public:
+ std::type_index GetTypeIndex() const { return type_index_; }
+
+ template <typename T>
+ Mapper<T>* StaticCast() {
+ return static_cast<Mapper<T>*>(this);
+ }
+
+ template <typename T>
+ Mapper<T>* DynamicCast() {
+ return dynamic_cast<Mapper<T>*>(this);
+ }
+
+ private:
+ std::type_index type_index_;
+};
+
+template <typename T>
+class CRU_UI_API BasicMapper : public MapperBase {
+ public:
+ BasicMapper() : MapperBase(typeid(T)) {}
+
+ CRU_DELETE_COPY(BasicMapper)
+ CRU_DELETE_MOVE(BasicMapper)
+
+ ~BasicMapper() override;
+
+ virtual bool SupportMapFromString() { return false; }
+ virtual std::unique_ptr<T> MapFromString(String str) {
+ if (!SupportMapFromString()) {
+ throw Exception(u"This mapper does not support map from string.");
+ }
+
+ return DoMapFromString(str);
+ }
+
+ virtual bool SupportMapFromXml() { return false; }
+ virtual bool XmlElementIsOfThisType(xml::XmlElementNode* node) {
+ return false;
+ }
+ std::unique_ptr<T> MapFromXml(xml::XmlElementNode* node) {
+ if (!SupportMapFromXml()) {
+ throw new Exception(u"This mapper does not support map from xml.");
+ }
+
+ if (!XmlElementIsOfThisType(node)) {
+ throw new Exception(u"This xml element is not of mapping type.");
+ }
+
+ return DoMapFromXml(node);
+ }
+
+ protected:
+ virtual std::unique_ptr<T> DoMapFromString(String str) { return nullptr; }
+ virtual std::unique_ptr<T> DoMapFromXml(xml::XmlElementNode* node) {
+ return nullptr;
+ }
+};
+} // namespace cru::ui::mapper
diff --git a/include/cru/ui/mapper/MapperRegistry.hpp b/include/cru/ui/mapper/MapperRegistry.hpp
new file mode 100644
index 00000000..a170440d
--- /dev/null
+++ b/include/cru/ui/mapper/MapperRegistry.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "Mapper.hpp"
+
+#include <memory>
+#include <vector>
+
+namespace cru::ui::mapper {
+class CRU_UI_API MapperRegistry {
+ public:
+ MapperRegistry();
+
+ CRU_DELETE_COPY(MapperRegistry)
+ CRU_DELETE_MOVE(MapperRegistry)
+
+ ~MapperRegistry();
+
+ const std::vector<MapperBase*>& GetAllMappers() const { return mapper_list_; }
+
+ void RegisterMapper(MapperBase* mapper);
+ void UnregisterMapper(MapperBase* mapper);
+
+ private:
+ std::vector<MapperBase*> mapper_list_;
+};
+} // namespace cru::ui::mapper