2016-08-07 12:52:48 -07:00
|
|
|
///
|
2016-08-17 16:48:24 -07:00
|
|
|
/// @file eo_promise.hh
|
2016-08-07 12:52:48 -07:00
|
|
|
///
|
|
|
|
|
|
|
|
#ifndef EFL_CXX_EO_PROMISE_HH
|
|
|
|
#define EFL_CXX_EO_PROMISE_HH
|
|
|
|
|
|
|
|
#include <Efl.h>
|
|
|
|
|
|
|
|
#include <Eina.hh>
|
|
|
|
#include <Ecore_Manual.hh>
|
|
|
|
|
|
|
|
#include <mutex>
|
|
|
|
#include <condition_variable>
|
|
|
|
|
2016-08-15 10:47:16 -07:00
|
|
|
#include <eina_tuple.hh>
|
2016-08-17 16:48:24 -07:00
|
|
|
#include <eo_promise_meta.hh>
|
2016-09-13 20:33:02 -07:00
|
|
|
#include <eo_future.hh>
|
2016-08-15 10:47:16 -07:00
|
|
|
|
2016-08-07 12:52:48 -07:00
|
|
|
namespace efl {
|
|
|
|
|
2016-08-15 10:47:16 -07:00
|
|
|
template <typename...Args>
|
|
|
|
struct shared_future;
|
|
|
|
|
2016-08-17 16:48:24 -07:00
|
|
|
namespace _impl {
|
|
|
|
|
|
|
|
struct promise_common
|
|
|
|
{
|
|
|
|
explicit promise_common(Efl_Promise* _promise) : _promise(_promise) {}
|
|
|
|
explicit promise_common(std::nullptr_t) : _promise(nullptr) {}
|
|
|
|
promise_common()
|
|
|
|
{
|
|
|
|
_promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
|
|
|
|
}
|
|
|
|
~promise_common()
|
|
|
|
{
|
|
|
|
if(_promise)
|
|
|
|
::efl_unref(_promise);
|
|
|
|
}
|
|
|
|
promise_common(promise_common const& other)
|
|
|
|
: _promise( ::efl_ref(other._promise))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
promise_common(promise_common&& other)
|
|
|
|
: _promise(nullptr)
|
|
|
|
{
|
|
|
|
std::swap(*this, other);
|
|
|
|
}
|
|
|
|
promise_common& operator=(promise_common const& other)
|
|
|
|
{
|
|
|
|
_promise = ::efl_ref(other._promise);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
promise_common& operator=(promise_common&& other)
|
|
|
|
{
|
|
|
|
std::swap(*this, other);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
bool valid() const
|
|
|
|
{
|
|
|
|
return _promise != nullptr;
|
|
|
|
}
|
|
|
|
void swap(promise_common& other)
|
|
|
|
{
|
|
|
|
std::swap(*this, other);
|
|
|
|
}
|
|
|
|
void set_exception(std::exception_ptr /*p*/)
|
|
|
|
{
|
|
|
|
}
|
2016-08-15 10:47:16 -07:00
|
|
|
|
2016-08-17 16:48:24 -07:00
|
|
|
Efl_Promise* _promise;
|
|
|
|
};
|
2016-09-20 19:30:13 -07:00
|
|
|
|
|
|
|
template <typename P>
|
|
|
|
struct promise_progress : promise_common
|
2016-08-07 12:52:48 -07:00
|
|
|
{
|
2016-09-20 19:30:13 -07:00
|
|
|
void set_progress(P const& progress)
|
|
|
|
{
|
|
|
|
efl_promise_progress_set(this->_promise, &progress);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct promise_progress<void> : promise_common
|
|
|
|
{
|
|
|
|
void set_progress()
|
|
|
|
{
|
|
|
|
efl_promise_progress_set(this->_promise, nullptr);
|
|
|
|
}
|
|
|
|
};
|
2016-08-07 12:52:48 -07:00
|
|
|
|
2016-09-20 19:30:13 -07:00
|
|
|
template <typename T, typename Progress>
|
|
|
|
struct promise_1_type : promise_progress<Progress>
|
|
|
|
{
|
2016-08-17 16:48:24 -07:00
|
|
|
void set_value(T const& v)
|
|
|
|
{
|
|
|
|
typedef typename eina::alloc_to_c_traits<T>::c_type c_type;
|
|
|
|
c_type* c_value = eina::alloc_to_c_traits<T>::copy_alloc(v);
|
|
|
|
efl_promise_value_set(this->_promise, c_value, & eina::alloc_to_c_traits<T>::free_alloc);
|
|
|
|
}
|
|
|
|
void set_value(T&& v)
|
|
|
|
{
|
|
|
|
typedef typename eina::alloc_to_c_traits<T>::c_type c_type;
|
|
|
|
c_type* c_value = eina::alloc_to_c_traits<T>::copy_alloc(std::move(v));
|
|
|
|
efl_promise_value_set(this->_promise, c_value, & eina::alloc_to_c_traits<T>::free_alloc);
|
|
|
|
}
|
2016-08-07 12:52:48 -07:00
|
|
|
};
|
2016-08-17 16:48:24 -07:00
|
|
|
|
2016-09-20 19:30:13 -07:00
|
|
|
template <typename Progress>
|
|
|
|
struct promise_1_type<void, Progress> : promise_progress<Progress>
|
2016-08-17 16:48:24 -07:00
|
|
|
{
|
|
|
|
void set_value()
|
|
|
|
{
|
|
|
|
efl_promise_value_set(this->_promise, nullptr, nullptr);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename Progress = void>
|
2016-09-20 19:30:13 -07:00
|
|
|
struct promise : private _impl::promise_1_type<T, Progress>
|
2016-08-17 16:48:24 -07:00
|
|
|
{
|
2016-09-20 19:30:13 -07:00
|
|
|
typedef _impl::promise_1_type<T, Progress> _base_type;
|
2016-08-17 16:48:24 -07:00
|
|
|
using _base_type::_base_type;
|
|
|
|
using _base_type::set_value;
|
2016-09-20 19:30:13 -07:00
|
|
|
using _base_type::set_progress;
|
2016-08-17 16:48:24 -07:00
|
|
|
using _base_type::set_exception;
|
|
|
|
|
2016-09-20 19:30:13 -07:00
|
|
|
shared_future<T, progress<Progress>> get_future()
|
2016-08-17 16:48:24 -07:00
|
|
|
{
|
2016-09-20 19:30:13 -07:00
|
|
|
return shared_future<T, progress<Progress>>{ ::efl_ref( ::efl_promise_future_get(this->_promise)) };
|
2016-08-17 16:48:24 -07:00
|
|
|
}
|
|
|
|
|
2016-09-20 19:30:13 -07:00
|
|
|
void swap(promise<T, progress<Progress>>& other)
|
2016-08-17 16:48:24 -07:00
|
|
|
{
|
|
|
|
_base_type::swap(other);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename...Args>
|
|
|
|
void swap(promise<Args...>& lhs, promise<Args...>& rhs)
|
|
|
|
{
|
|
|
|
lhs.swap(rhs);
|
|
|
|
}
|
|
|
|
|
2016-08-07 12:52:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|