Omnidome
Fulldome Mapping Software Toolkit
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ContextBoundPtr.h
Go to the documentation of this file.
1 /* Copyright (c) 2014-2015 "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 
20 #ifndef OMNI_VISUAL_CONTEXTBOUNDPTR_H_
21 #define OMNI_VISUAL_CONTEXTBOUNDPTR_H_
22 
23 #include <memory>
24 #include <QOpenGLContext>
25 #include <QOpenGLFramebufferObject>
27 
28 namespace omni {
29  namespace visual {
30 
31  template<typename T, typename DELETER>
33 
34  namespace detail {
35  /// The internal structure responsible for deleting the object
36  template<typename T, typename DELETER = std::default_delete<T>>
39  template<typename PTR>
40  ContextBoundPtrInternal(PTR *_ptr, QOpenGLContext *_context) {
41  connection_ = QObject::connect(_context,
42  &QOpenGLContext::aboutToBeDestroyed,
43  [&]() {
44  delete this;
45  });
46  ptr_ = _ptr;
47  context_ = _context;
48  surface_ = _context->surface();
49  }
50 
52  QObject::disconnect(connection_);
53  if (!QOpenGLContext::currentContext()) return;
54 
55  /// Make sure object is destroyed in its context
56  contextSwitch(context_,[&](QOpenGLFunctions& _) {
57  if (ptr_) {
58  DELETER()(ptr_);
59  ptr_ = nullptr;
60  }
61  });
62  }
63 
64  private:
65  QMetaObject::Connection connection_;
66  T *ptr_ = nullptr;
67  QSurface *surface_ = nullptr;
68  QOpenGLContext *context_ = nullptr;
69  };
70  }
71 
72  /**@brief A pointer template which is free'd together with its context
73  @detail Holds an internal object which is responsible for freeing the
74  held object when OpenGL context is free'd.
75  **/
76  template<typename T, typename DELETER = std::default_delete<T>>
77  struct ContextBoundPtr {
79 
80  template<typename PTR>
81  ContextBoundPtr(PTR *_p,
82  QOpenGLContext *_context =
83  QOpenGLContext::globalShareContext()) {
84  reset(_p, _context);
85  }
86 
88  // Internal is not deleted here because its done by the bound context
89  //reset();
90  }
91 
92  /// Delete copy constructor
93  ContextBoundPtr(const ContextBoundPtr& that) = delete;
94 
95  /// Delete copy assignment operator
96  ContextBoundPtr& operator=(const ContextBoundPtr&) = delete;
97 
98  /// Delete held object and internal state
99  void reset() {
100  if (internal_) {
101  delete internal_;
102  internal_ = nullptr;
103  }
104  }
105 
106  /// Reset and and assign neew pointer
107  template<typename PTR>
108  T* reset(PTR *_p,
109  QOpenGLContext *_context = QOpenGLContext::globalShareContext()) {
110  /// Reset and make new internal object
111  reset();
112  /// No initialization without context!
113  bool _valid = _context ? _context->surface() != nullptr : false;
114  if (!_valid) {
115  return nullptr;
116  }
117 
119 
120  return get();
121  }
122 
123  T* get() const {
124  return internal_ ? internal_->ptr_ : nullptr;
125  }
126 
127  /// Cast to bool operator. Return true if pointer is not null
128  explicit operator bool() const {
129  return get() != nullptr;
130  }
131 
132  /// Return reference
133  typename std::add_lvalue_reference<T>::type operator*() const {
134  return *get();
135  }
136 
137  T * operator->() const {
138  return get();
139  }
140 
141  /// Return pointer to associated context
142  QOpenGLContext* context() const {
143  return internal_ ? internal_->context_ : nullptr;
144  }
145 
146  private:
148  };
149  }
150 
152 }
153 
154 #endif /* OMNI_VISUAL_CONTEXTBOUNDPTR_H_ */
T * ptr_
Definition: ContextBoundPtr.h:66
void reset()
Delete held object and internal state.
Definition: ContextBoundPtr.h:99
ContextBoundPtr(PTR *_p, QOpenGLContext *_context=QOpenGLContext::globalShareContext())
Definition: ContextBoundPtr.h:81
The internal structure responsible for deleting the object.
Definition: ContextBoundPtr.h:37
void contextSwitch(QOpenGLContext *_context, ContextFunctor f)
Definition: ContextSwitch.cpp:25
QMetaObject::Connection connection_
Definition: ContextBoundPtr.h:65
ContextBoundPtr & operator=(const ContextBoundPtr &)=delete
Delete copy assignment operator.
QOpenGLContext * context_
Definition: ContextBoundPtr.h:68
~ContextBoundPtrInternal()
Definition: ContextBoundPtr.h:51
T * operator->() const
Definition: ContextBoundPtr.h:137
ContextBoundPtr()
Definition: ContextBoundPtr.h:78
QOpenGLContext * context() const
Return pointer to associated context.
Definition: ContextBoundPtr.h:142
~ContextBoundPtr()
Definition: ContextBoundPtr.h:87
T * reset(PTR *_p, QOpenGLContext *_context=QOpenGLContext::globalShareContext())
Reset and and assign neew pointer.
Definition: ContextBoundPtr.h:108
QSurface * surface_
Definition: ContextBoundPtr.h:67
detail::ContextBoundPtrInternal< T > * internal_
Definition: ContextBoundPtr.h:147
std::add_lvalue_reference< T >::type operator*() const
Return reference.
Definition: ContextBoundPtr.h:133
ContextBoundPtrInternal(PTR *_ptr, QOpenGLContext *_context)
Definition: ContextBoundPtr.h:40
A pointer template which is free'd together with its context Holds an internal object which is respo...
Definition: ContextBoundPtr.h:32