ComponentSerialization.hpp
1 #pragma once
2 #include <score/model/Component.hpp>
3 #if defined(SCORE_SERIALIZABLE_COMPONENTS)
4 #include <score/plugins/InterfaceList.hpp>
5 #include <score/plugins/SerializableInterface.hpp>
6 
7 #include <type_traits>
8 
9 namespace score
10 {
11 
18 class SCORE_LIB_BASE_EXPORT DataStreamSerializedComponents : public score::Component
19 {
20  COMMON_COMPONENT_METADATA("a0c8de61-c18f-4aca-8b21-cf71451f4970")
21 public:
22  static const constexpr bool is_unique = true;
23  DataStreamSerializedComponents(
24  const Id<score::Component>& id, DataStreamComponents obj, QObject* parent);
25  virtual ~DataStreamSerializedComponents();
26 
28  bool deserializeRemaining(score::Components& comps, QObject* entity);
29 
30  bool finished() const { return data.empty(); }
31 
32  DataStreamComponents data;
33 };
34 
35 class SCORE_LIB_BASE_EXPORT JSONSerializedComponents : public score::Component
36 {
37  COMMON_COMPONENT_METADATA("37939615-7165-4bb0-9cdd-e7426153d222")
38 public:
39  static const constexpr bool is_unique = true;
40  JSONSerializedComponents(
41  const Id<score::Component>& id, JSONComponents obj, QObject* parent);
42 
43  virtual ~JSONSerializedComponents();
44 
46  bool deserializeRemaining(score::Components& comps, QObject* entity);
47 
48  bool finished() const { return data.empty(); }
49 
50  JSONComponents data;
51 };
52 
53 class SCORE_LIB_BASE_EXPORT SerializableComponent
54  : public score::Component
55  , public score::SerializableInterface<score::SerializableComponent>
56 {
57 public:
58  using score::Component::Component;
59 
60  template <typename Vis>
61  SerializableComponent(Vis& vis, QObject* parent)
62  : score::Component{vis, parent}
63  {
64  }
65 
66  virtual InterfaceKey interfaceKey() const = 0;
67 };
68 
69 struct SCORE_LIB_BASE_EXPORT SerializableComponentFactory : public score::InterfaceBase
70 {
71  SCORE_INTERFACE(SerializableComponentFactory, "ffafadc2-0ce7-45d8-b673-d9238c37d018")
72 public:
73  ~SerializableComponentFactory() override;
74  virtual score::SerializableComponent* make(
75  const Id<score::Component>& id, const score::DocumentContext& ctx, QObject* parent)
76  = 0;
77 
78  virtual score::SerializableComponent*
79  load(const VisitorVariant& vis, const score::DocumentContext& ctx, QObject* parent)
80  = 0;
81 };
82 
83 struct SCORE_LIB_BASE_EXPORT SerializableComponentFactoryList
84  : public score::InterfaceList<SerializableComponentFactory>
85 {
86  using object_type = score::SerializableComponent;
87  ~SerializableComponentFactoryList();
88  score::SerializableComponent* loadMissing(
89  const VisitorVariant& vis, const score::DocumentContext& ctx,
90  QObject* parent) const;
91 };
92 
93 template <typename System_T>
94 class GenericSerializableComponent : public score::SerializableComponent
95 {
96 public:
97  template <typename... Args>
98  GenericSerializableComponent(System_T& sys, Args&&... args)
99  : score::SerializableComponent{std::forward<Args>(args)...}
100  , m_system{sys}
101  {
102  }
103 
104  System_T& system() const { return m_system; }
105 
106 private:
107  System_T& m_system;
108 };
109 
110 struct serializable_tag
111 {
112 };
113 struct not_serializable_tag
114 {
115 };
116 
117 template <typename T, typename = void>
118 struct is_component_serializable
119 {
120  using type = score::not_serializable_tag;
121  static constexpr bool value = false;
122 };
123 
124 template <typename T>
125 struct is_component_serializable<
126  T, std::enable_if_t<std::is_base_of<score::SerializableComponent, T>::value>>
127 {
128  using type = score::serializable_tag;
129  static constexpr bool value = true;
130 };
131 
132 template <typename Component_T, typename Fun>
133 auto deserialize_component(score::Components& comps, Fun f)
134 {
135  if(auto datastream_ser = findComponent<DataStreamSerializedComponents>(comps))
136  {
137  auto& data = datastream_ser->data;
138  auto it = data.find(Component_T::static_key());
139  if(it != data.end())
140  {
141  DataStream::Deserializer des{it->second};
142  auto res = f(des);
143  if(res)
144  {
145  data.erase(it);
146  }
147  return res;
148  }
149  }
150  else if(auto json_ser = findComponent<JSONSerializedComponents>(comps))
151  {
152  auto& data = json_ser->data;
153  auto it = data.find(Component_T::static_key());
154  if(it != data.end())
155  {
156  JSONObject::Deserializer des{it->second};
157  auto res = f(des);
158  if(res)
159  {
160  data.erase(it);
161  }
162  return res;
163  }
164  }
165 }
166 
167 SCORE_LIB_BASE_EXPORT
168 void deserializeRemainingComponents(score::Components& comps, QObject* obj);
169 }
170 #endif
Definition: DataStreamVisitor.hpp:202
Definition: JSONVisitor.hpp:423
The id_base_t class.
Definition: Identifier.hpp:57
A component adds custom data to an Entity.
Definition: lib/score/model/Component.hpp:25
Base class for plug-in interfaces.
Definition: Interface.hpp:52
Generic serialization method for abstract classes.
Definition: SerializableInterface.hpp:21
Base toolkit upon which the software is built.
Definition: Application.cpp:90
The VisitorVariant struct.
Definition: VisitorInterface.hpp:26
Definition: lib/score/model/Component.hpp:41
Definition: DocumentContext.hpp:18