summaryrefslogtreecommitdiff
path: root/src/bindings/eo_cxx/eo_wref.hh
blob: 4e2385f2d3029a8bf8ae3930f253a1627f3dc79f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

///
/// @file eo_wref.hh
///

#ifndef EFL_CXX_WREF_HH
#define EFL_CXX_WREF_HH

#include <eina_optional.hh>

#include "eo_ops.hh"

namespace efl { namespace eo {

/// @addtogroup Efl_Cxx_API
/// @{

/// @brief Weak references to an <em>EO Object</em>.
///
template<typename T>
struct wref {

   /// @brief Class constructor.
   ///
   /// @param obj The <em>EO Object</em> to be referenced.
   ///
   /// Create a weak reference to @p obj.
   ///
   explicit wref(Eo* obj) : _eo_wref(obj)
   {
      _add();
   }

   /// @brief Class constructor.
   ///
   /// @param obj The <em>EO C++ Object</em> to be referenced.
   ///
   /// Create a weak reference to @p obj.
   ///
   wref(T obj) : _eo_wref(obj._eo_ptr())
   {
      _add();
   }

   /// @brief Class destructor.
   ///
   ~wref()
   {
      if(eina::optional<T> p = lock())
        _del();
   }

   /// @brief Try to acquire a strong reference to the underlying
   /// <em>EO Object</em>.
   ///
   /// This function checks whether the weak reference still points to
   /// a valid <em>EO Object</em>. If the reference is still valid it
   /// increments the reference counter of the object and returns a
   /// pointer to it.
   ///
   /// @return If the lock was successfully acquired it returns a
   /// strong reference to the <em>EO Object</em>. Otherwise it returns
   /// an empty eina::optional.
   ///
   eina::optional<T> lock()
   {
      if(_eo_wref) // XXX eo_ref() should work on multi-threaded environments
        {
           detail::ref(_eo_wref);
        }
      else
        {
           return nullptr;
        }
      return T(_eo_wref);
   }

   /// @brief Copy constructor.
   ///
   wref(wref const& other)
     : _eo_wref(other._eo_wref)
   {
      if(eina::optional<T> p = lock())
        {
           _add();
        }
      else
        {
           _eo_wref = 0;
        }
   }

   /// @brief Assignment operator.
   ///
   wref& operator=(wref const& other)
   {
      _eo_wref = other._eo_wref;
      if(eina::optional<T> p = lock())
        {
           _add();
        }
      else
        {
           _eo_wref = 0;
        }
   }

private:
   void _add()
   {
      detail::wref_add(_eo_wref, &_eo_wref);
   }

   void _del()
   {
      detail::wref_del(_eo_wref, &_eo_wref);
   }

   Eo* _eo_wref; ///< The weak reference.
};

/// @}

} } // namespace efl { namespace eo {

#endif // EFL_CXX_WREF_HH