Omnidome
Fulldome Mapping Software Toolkit
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DataModel.h
Go to the documentation of this file.
1 /* Copyright (c) 2014-2016 "Omnidome" by cr8tr
2  * Dome Mapping Projection Software (http://omnido.me).
3  * Omnidome was created by Michael Winkelmann aka Wilston Oreo (@WilstonOreo)
4  *
5  * This file is part of Omnidome.
6  *
7  * Omnidome is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU Affero General Public License for more details.
16  * You should have received a copy of the GNU Affero General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 #ifndef OMNI_UI_MIXIN_DATAMODEL_H_
20 #define OMNI_UI_MIXIN_DATAMODEL_H_
21 
22 #include <set>
23 #include <memory>
24 #include <QObject>
25 #include "Locked.h"
26 
27 namespace omni {
28  namespace ui {
29  namespace mixin {
30  namespace detail {
31  /// Pointer type handler
32  template<typename T, bool SHARED>
33  struct PointerType {};
34 
35  /// Use std::shared_ptr when shared is true
36  template<typename T>
37  struct PointerType<T, true>{
38  typedef T data_type;
39  typedef std::shared_ptr<T>type;
40 
41  static void initialize(type& _t) {
42  }
43 
44  static T* raw_pointer(type _t) {
45  return _t.get();
46  }
47 
48  static T const* raw_pointer_const(type _t) {
49  return _t.get();
50  }
51  };
52 
53  /// Use raw pointer (T*) when shared is false
54  template<typename T>
55  struct PointerType<T, false>{
56  typedef T *type;
57 
58  static void initialize(type& _t) {
59  _t = nullptr;
60  }
61 
62  static T* raw_pointer(type _t) {
63  return _t;
64  }
65 
66  static T const* raw_pointer_const(const type _t) {
67  return _t;
68  }
69  };
70  }
71 
72  /// Data model interface
74  public:
75  /// Update the data model interface
76  virtual void updateDataModel() = 0;
77  virtual void updateFrontend() = 0;
78  };
79 
80 
81  /**@brief Holds a specific data model with frontend update mechanism
82  @tparam DATAMODEL Type of data which is stored
83  @tparam SHARED Boolean flag to tell of data model is
84  encapsulared in a shared_ptr
85  **/
86  template<typename DATAMODEL, bool SHARED>
87  class DataModel :
88  public DataModelInterface,
89  protected Locked {
90  public:
91 
92  /// Data type
93  typedef DATAMODEL data_model_type;
94 
95  /// This type
97 
98  /// Pointer type handler
101 
102  /// Derived pointer type
103  typedef typename pointer_type_handler::type pointer_type;
104 
106  pointer_type_handler::initialize(dataModel_);
107  }
108 
109  /// Set new data model
110  void setDataModel(pointer_type _dataModel) {
111  this->locked([&]() {
112  dataModel_ = _dataModel;
113  updateFrontend();
114  });
115  }
116 
117  /// Return pointer to data model
119  return dataModel_;
120  }
121 
122  /// Return pointer to data model (const version)
123  const pointer_type dataModel() const {
124  return dataModel_;
125  }
126 
127  /// Push data to frontend widgets and all child widgets
128  virtual void updateFrontend() {
129  if (dataModel_ && this->isLocked()) {
130  dataToFrontend();
131  }
132  }
133 
134  virtual void updateDataModel() {
135  if (this->isLocked()) {
136  return;
137  }
138  this->locked([&]() {
139  if (frontendToData()) {
141  }
142  });
143  }
144 
145  private:
146  /**@brief Pure virtual method which determines how data model is represented in frontend
147  **/
148  virtual void dataToFrontend() = 0;
149 
150  /// Return true if data has changed by front end
151  virtual bool frontendToData() = 0;
152 
153  /// Internal method used to emit dataModelChanged signal
154  inline virtual void emitDataModelChangedSignal() {}
155 
157  };
158 
159  /// Template alias for shared data model
160  template<typename T>
162 
163  /// Template alias for unshared data model
164  template<typename T>
166 
167  /**@brief Instantiate a new widget and set data model
168  @detail Uses raw pointer (unshared data model)
169  **/
170  template<typename WIDGET, typename DATAMODEL, typename ... ARGS>
171  static WIDGET* makeWidget(DATAMODEL *_dataModel, ARGS&& ... _args) {
172  auto *_widget = new WIDGET(_args ...);
173 
174  _widget->setDataModel(_dataModel);
175  return _widget;
176  }
177 
178  /**@brief Instantiate a new widget and set data model
179  @detail Uses shared pointer (shared data model)
180  **/
181  template<typename WIDGET, typename DATAMODEL, typename ... ARGS>
182  static WIDGET* makeWidget(std::shared_ptr<DATAMODEL>_dataModel,
183  ARGS&& ... _args) {
184  auto *_widget = new WIDGET(_args ...);
185 
186  _widget->setDataModel(_dataModel);
187  return _widget;
188  }
189  }
190 
191  using mixin::DataModel;
194  using mixin::makeWidget;
195  }
196 }
197 
198 /// This macro needs to be inserted for every widget that uses DataModel
199 #define OMNI_UI_DATAMODEL(MODEL, SHARED) \
200  public: \
201  typedef omni::ui::mixin::DataModel<MODEL, SHARED>mixin_data_model_type; \
202  inline void updateDataModel() { \
203  mixin_data_model_type::updateDataModel(); \
204  } \
205  inline void updateFrontend() { \
206  this->locked([&]() { \
207  mixin_data_model_type::updateFrontend(); \
208  update(); \
209  }); \
210  } \
211  private: \
212  void emitDataModelChangedSignal() { \
213  emit dataModelChanged(); \
214  } \
215  public:
216 #define OMNI_UI_SHARED_DATAMODEL(MODEL) \
217  OMNI_UI_DATAMODEL(MODEL, true)
218 
219 #define OMNI_UI_UNSHARED_DATAMODEL(MODEL) \
220  OMNI_UI_DATAMODEL(MODEL, false)
221 
222 #endif /* OMNI_UI_MIXIN_DATAMODEL_H_ */
DataModel< T, true > SharedDataModel
Template alias for shared data model.
Definition: DataModel.h:161
DataModel< T, false > UnsharedDataModel
Template alias for unshared data model.
Definition: DataModel.h:165
pointer_type dataModel()
Return pointer to data model.
Definition: DataModel.h:118
static T * raw_pointer(type _t)
Definition: DataModel.h:62
static WIDGET * makeWidget(DATAMODEL *_dataModel, ARGS &&..._args)
Instantiate a new widget and set data model Uses raw pointer (unshared data model) ...
Definition: DataModel.h:171
Mixin with a function to lock the widget temporarily.
Definition: Locked.h:26
pointer_type dataModel_
Definition: DataModel.h:156
pointer_type_handler::type pointer_type
Derived pointer type.
Definition: DataModel.h:103
static T const * raw_pointer_const(type _t)
Definition: DataModel.h:48
static T const * raw_pointer_const(const type _t)
Definition: DataModel.h:66
DataModel< data_model_type, SHARED > type
This type.
Definition: DataModel.h:96
void locked(F f)
Lock widget and execute given functor.
Definition: Locked.h:30
Data model interface.
Definition: DataModel.h:73
const pointer_type dataModel() const
Return pointer to data model (const version)
Definition: DataModel.h:123
static void initialize(type &_t)
Definition: DataModel.h:41
detail::PointerType< data_model_type, SHARED > pointer_type_handler
Pointer type handler.
Definition: DataModel.h:100
virtual void updateDataModel()=0
Update the data model interface.
static void initialize(type &_t)
Definition: DataModel.h:58
bool isLocked() const
Return true if widget is locked.
Definition: Locked.h:40
Pointer type handler.
Definition: DataModel.h:33
void setDataModel(pointer_type _dataModel)
Set new data model.
Definition: DataModel.h:110
Holds a specific data model with frontend update mechanism.
Definition: DataModel.h:87
static T * raw_pointer(type _t)
Definition: DataModel.h:44
virtual bool frontendToData()=0
Return true if data has changed by front end.
virtual void dataToFrontend()=0
Pure virtual method which determines how data model is represented in frontend.
virtual void updateDataModel()
Update the data model interface.
Definition: DataModel.h:134
DATAMODEL data_model_type
Data type.
Definition: DataModel.h:93
DataModel()
Definition: DataModel.h:105
virtual void updateFrontend()
Push data to frontend widgets and all child widgets.
Definition: DataModel.h:128
std::shared_ptr< T > type
Definition: DataModel.h:39
virtual void emitDataModelChangedSignal()
Internal method used to emit dataModelChanged signal.
Definition: DataModel.h:154