mirror of
https://github.com/Naios/continuable.git
synced 2026-02-07 10:19:46 +08:00
Allow shorthand completion for continuables
This commit is contained in:
parent
d40f6d5c08
commit
a2dd086c80
@ -62,24 +62,24 @@ namespace detail
|
|||||||
template<typename _CTy, typename... Args>
|
template<typename _CTy, typename... Args>
|
||||||
struct WeakProxyFactory<_CTy, std::weak_ptr<std::function<void(Args...)>>>
|
struct WeakProxyFactory<_CTy, std::weak_ptr<std::function<void(Args...)>>>
|
||||||
{
|
{
|
||||||
static Callback<Args...> CreateProxy(_CTy&& weak)
|
static Callback<Args...> CreateProxy(_CTy&& weak)
|
||||||
{
|
{
|
||||||
return [=](Args&&... args)
|
return [=](Args&&... args)
|
||||||
{
|
{
|
||||||
if (auto const callback = weak.lock())
|
if (auto const callback = weak.lock())
|
||||||
(*callback)(std::forward<Args>(args)...);
|
(*callback)(std::forward<Args>(args)...);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _CTy, typename... Args>
|
template<typename _CTy, typename... Args>
|
||||||
struct WeakProxyFactory<_CTy, std::shared_ptr<std::function<void(Args...)>>>
|
struct WeakProxyFactory<_CTy, std::shared_ptr<std::function<void(Args...)>>>
|
||||||
{
|
{
|
||||||
static Callback<Args...> CreateProxy(_CTy&& shared)
|
static Callback<Args...> CreateProxy(_CTy&& shared)
|
||||||
{
|
{
|
||||||
return WeakProxyFactory<std::weak_ptr<std::function<void(Args...)>>&&,
|
return WeakProxyFactory<std::weak_ptr<std::function<void(Args...)>>&&,
|
||||||
std::weak_ptr<std::function<void(Args...)>>>::CreateProxy(std::forward<_CTy>(shared));
|
std::weak_ptr<std::function<void(Args...)>>>::CreateProxy(std::forward<_CTy>(shared));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // detail
|
} // detail
|
||||||
|
|||||||
@ -23,7 +23,9 @@
|
|||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
template<typename _Cain, typename _Proxy>
|
/// The internal state of the continuable
|
||||||
|
/// which is used to save certain internal types.
|
||||||
|
template<typename... Args>
|
||||||
struct ContinuableState;
|
struct ContinuableState;
|
||||||
|
|
||||||
template<typename... _Cain, typename _Proxy>
|
template<typename... _Cain, typename _Proxy>
|
||||||
@ -31,16 +33,28 @@ namespace detail
|
|||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef ContinuableState<std::tuple<>, void> EmptyContinuableState;
|
typedef ContinuableState<std::tuple<>, void> DefaultContinuableState;
|
||||||
|
|
||||||
} // detail
|
/// The unwrap which is used to extract continuable parameter types.
|
||||||
|
template<typename... Args>
|
||||||
|
struct continuable_unwrap;
|
||||||
|
|
||||||
template<typename _CTy, typename _State = detail::EmptyContinuableState>
|
// First parameter is the state.
|
||||||
class Continuable;
|
template<typename... _SArgs, typename... _CArgs>
|
||||||
|
struct continuable_unwrap<ContinuableState<_SArgs...>, _CArgs...>
|
||||||
|
{
|
||||||
|
typedef ContinuableState<_SArgs...> state_t;
|
||||||
|
|
||||||
|
typedef Callback<_CArgs...> callback_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
// No state is given use an empty one.
|
||||||
|
template<typename... _CArgs>
|
||||||
|
struct continuable_unwrap<_CArgs...>
|
||||||
|
: public continuable_unwrap<DefaultContinuableState, _CArgs...> { };
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
/// Corrects void return types from functional types which should be Continuable<Callback<>>
|
/// Corrects void return types from functional types which should be Continuable<Callback<>>
|
||||||
|
/*
|
||||||
template<typename _RTy>
|
template<typename _RTy>
|
||||||
struct convert_void_to_continuable;
|
struct convert_void_to_continuable;
|
||||||
|
|
||||||
@ -55,91 +69,110 @@ namespace detail
|
|||||||
{
|
{
|
||||||
typedef Continuable<_CArgs...> type;
|
typedef Continuable<_CArgs...> type;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... _ATy, typename _State>
|
|
||||||
class Continuable<std::function<void(_ATy...)>, _State>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef std::function<void(Callback<_ATy...>&&)> ForwardFunction;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// Functional which expects a callback that is inserted from the Continuable
|
|
||||||
/// to chain everything together
|
|
||||||
ForwardFunction _callback_insert;
|
|
||||||
|
|
||||||
bool _released;
|
|
||||||
|
|
||||||
void Dispatch()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// Deleted copy construct
|
|
||||||
template<typename _RCTy, typename _RState>
|
|
||||||
Continuable(Continuable<_RCTy, _RState> const&) = delete;
|
|
||||||
|
|
||||||
/// Move construct
|
|
||||||
template<typename _RCTy, typename _RState>
|
|
||||||
Continuable(Continuable<_RCTy, _RState>&& right)
|
|
||||||
: _released(right._released)
|
|
||||||
{
|
|
||||||
right._released = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct through a ForwardFunction
|
|
||||||
template<typename _FTy>
|
|
||||||
Continuable(_FTy&& callback_insert)
|
|
||||||
: _callback_insert(std::forward<_FTy>(callback_insert)), _released(false) { }
|
|
||||||
|
|
||||||
/// Destructor which calls the dispatch chain if needed.
|
|
||||||
~Continuable()
|
|
||||||
{
|
|
||||||
if (!_released)
|
|
||||||
{
|
|
||||||
_released = true;
|
|
||||||
Dispatch();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Deleted copy assign
|
|
||||||
template<typename _RCTy, typename _RState>
|
|
||||||
Continuable& operator= (Continuable<_RCTy, _RState> const&) = delete;
|
|
||||||
|
|
||||||
/// Move construct assign
|
|
||||||
template<typename _RCTy, typename _RState>
|
|
||||||
Continuable& operator= (Continuable<_RCTy, _RState>&& right)
|
|
||||||
{
|
|
||||||
_released = right._released;
|
|
||||||
right._released = true;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Accept only correct callbacks
|
|
||||||
template<typename _CTy>
|
|
||||||
Continuable<Callback<_ATy...>> then(_CTy&&)
|
|
||||||
{
|
|
||||||
// TODO Transmute the returned callback here.
|
|
||||||
return Continuable<Callback<_ATy...>>(std::move(*this));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
// TODO Accept only correct callbacks
|
|
||||||
template<typename... _CTy>
|
|
||||||
Continuable<Callback<_ATy...>> all(_CTy&&...)
|
|
||||||
{
|
|
||||||
// TODO Transmute the returned callback here.
|
|
||||||
return Continuable<Callback<_ATy...>>(std::move(*this));
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// Invalidates the Continuable
|
// ContinuableImpl Forward definition
|
||||||
Continuable& invalidate()
|
template<typename _STy, typename _CTy>
|
||||||
|
class _ContinuableImpl;
|
||||||
|
|
||||||
|
template<typename... _STy, typename... _ATy>
|
||||||
|
class _ContinuableImpl<ContinuableState<_STy...>, std::function<void(_ATy...)>>
|
||||||
{
|
{
|
||||||
_released = true;
|
// Make all instances of _ContinuableImpl to a friend.
|
||||||
return *this;
|
template<typename, typename>
|
||||||
}
|
friend class _ContinuableImpl;
|
||||||
};
|
|
||||||
|
typedef ContinuableState<_STy...> MyState;
|
||||||
|
typedef Callback<_ATy...> MyCallback;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef std::function<void(Callback<_ATy...>&&)> ForwardFunction;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Functional which expects a callback that is inserted from the Continuable
|
||||||
|
/// to chain everything together
|
||||||
|
ForwardFunction _callback_insert;
|
||||||
|
|
||||||
|
bool _released;
|
||||||
|
|
||||||
|
void Dispatch()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Deleted copy construct
|
||||||
|
template<typename _RState, typename _RCTy>
|
||||||
|
_ContinuableImpl(_ContinuableImpl<_RState, _RCTy> const&) = delete;
|
||||||
|
|
||||||
|
/// Move construct
|
||||||
|
template<typename _RState, typename _RCTy>
|
||||||
|
_ContinuableImpl(_ContinuableImpl<_RState, _RCTy>&& right)
|
||||||
|
: _released(right._released)
|
||||||
|
{
|
||||||
|
right._released = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct through a ForwardFunction
|
||||||
|
template<typename _FTy>
|
||||||
|
_ContinuableImpl(_FTy&& callback_insert)
|
||||||
|
: _callback_insert(std::forward<_FTy>(callback_insert)), _released(false) { }
|
||||||
|
|
||||||
|
/// Destructor which calls the dispatch chain if needed.
|
||||||
|
~_ContinuableImpl()
|
||||||
|
{
|
||||||
|
if (!_released)
|
||||||
|
{
|
||||||
|
_released = true;
|
||||||
|
Dispatch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deleted copy assign
|
||||||
|
template<typename _RState, typename _RCTy>
|
||||||
|
_ContinuableImpl& operator= (_ContinuableImpl<_RState, _RCTy> const&) = delete;
|
||||||
|
|
||||||
|
/// Move construct assign
|
||||||
|
template<typename _RState, typename _RCTy>
|
||||||
|
_ContinuableImpl& operator= (_ContinuableImpl<_RState, _RCTy>&& right)
|
||||||
|
{
|
||||||
|
_released = right._released;
|
||||||
|
right._released = true;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Accept only correct callbacks
|
||||||
|
template<typename _CTy>
|
||||||
|
_ContinuableImpl<DefaultContinuableState, Callback<_ATy...>> then(_CTy&&)
|
||||||
|
{
|
||||||
|
// TODO Transmute the returned callback here.
|
||||||
|
return _ContinuableImpl<DefaultContinuableState, Callback<_ATy...>>(std::move(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// TODO Accept only correct callbacks
|
||||||
|
template<typename... _CTy>
|
||||||
|
Continuable<Callback<_ATy...>> all(_CTy&&...)
|
||||||
|
{
|
||||||
|
// TODO Transmute the returned callback here.
|
||||||
|
return Continuable<Callback<_ATy...>>(std::move(*this));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// Invalidates the Continuable
|
||||||
|
_ContinuableImpl& invalidate()
|
||||||
|
{
|
||||||
|
_released = true;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A continuable provides useful methods to react on the result of callbacks
|
||||||
|
/// and allows to chain multiple callback calls to a chain.
|
||||||
|
template<typename... Args>
|
||||||
|
using Continuable = detail::_ContinuableImpl<
|
||||||
|
detail::DefaultContinuableState,
|
||||||
|
Callback<Args...>>;
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
@ -150,10 +183,10 @@ namespace detail
|
|||||||
struct ContinuableFactory<_FTy, _RTy, ::fu::identity<std::function<void(_ATy...)>&&>>
|
struct ContinuableFactory<_FTy, _RTy, ::fu::identity<std::function<void(_ATy...)>&&>>
|
||||||
{
|
{
|
||||||
static auto CreateFrom(_FTy&& functional)
|
static auto CreateFrom(_FTy&& functional)
|
||||||
-> Continuable<Callback<_ATy...>>
|
-> Continuable<_ATy...>
|
||||||
{
|
{
|
||||||
return Continuable<Callback<_ATy...>>(
|
return Continuable<_ATy...>(
|
||||||
typename Continuable<Callback<_ATy...>>::ForwardFunction(std::forward<_FTy>(functional)));
|
typename Continuable<_ATy...>::ForwardFunction(std::forward<_FTy>(functional)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
20
test.cpp
20
test.cpp
@ -19,7 +19,7 @@ enum SpellCastResult
|
|||||||
SPELL_FAILED_ALREADY_BEING_TAMED = 5
|
SPELL_FAILED_ALREADY_BEING_TAMED = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
Continuable<Callback<SpellCastResult>> CastSpell(int id)
|
Continuable<SpellCastResult> CastSpell(int id)
|
||||||
{
|
{
|
||||||
return make_continuable([=](Callback<SpellCastResult>&& callback)
|
return make_continuable([=](Callback<SpellCastResult>&& callback)
|
||||||
{
|
{
|
||||||
@ -38,11 +38,17 @@ void test_unwrap(std::string const& msg)
|
|||||||
|
|
||||||
int main(int /*argc*/, char** /*argv*/)
|
int main(int /*argc*/, char** /*argv*/)
|
||||||
{
|
{
|
||||||
|
Continuable<bool> cb = make_continuable([](Callback<bool>&& callback)
|
||||||
|
{
|
||||||
|
|
||||||
|
callback(true);
|
||||||
|
});
|
||||||
|
|
||||||
test_unwrap<void()>("void()");
|
test_unwrap<void()>("void()");
|
||||||
test_unwrap<std::function<void()>>("std::function<void()>");
|
test_unwrap<std::function<void()>>("std::function<void()>");
|
||||||
test_unwrap<std::vector<std::string>>("std::vector<std::string>");
|
test_unwrap<std::vector<std::string>>("std::vector<std::string>");
|
||||||
|
|
||||||
make_continuable([=](Callback<>&& /*callback*/)
|
make_continuable([=](Callback<>&&)
|
||||||
{
|
{
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -50,7 +56,7 @@ int main(int /*argc*/, char** /*argv*/)
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
++i;
|
++i;
|
||||||
|
|
||||||
auto lam = [=](Callback<SpellCastResult>&& /*callback*/)
|
auto lam = [=](Callback<SpellCastResult>&&)
|
||||||
{
|
{
|
||||||
// on success call the callback with SPELL_FAILED_SUCCESS
|
// on success call the callback with SPELL_FAILED_SUCCESS
|
||||||
// callback(SPELL_FAILED_SUCCESS);
|
// callback(SPELL_FAILED_SUCCESS);
|
||||||
@ -76,8 +82,8 @@ int main(int /*argc*/, char** /*argv*/)
|
|||||||
|
|
||||||
typedef Continuable<bool> cont123;
|
typedef Continuable<bool> cont123;
|
||||||
|
|
||||||
typedef Continuable<Callback<bool>> myty1;
|
typedef Continuable<bool> myty1;
|
||||||
typedef Continuable<Callback<bool>, float> myty2;
|
typedef Continuable<bool, float> myty2;
|
||||||
|
|
||||||
// Continuable<Callback<SpellCastResult>> spell
|
// Continuable<Callback<SpellCastResult>> spell
|
||||||
CastSpell(63362)
|
CastSpell(63362)
|
||||||
@ -107,9 +113,9 @@ int main(int /*argc*/, char** /*argv*/)
|
|||||||
typedef fu::requires_functional_constructible<std::function<void()>>::type test_assert1;
|
typedef fu::requires_functional_constructible<std::function<void()>>::type test_assert1;
|
||||||
// typedef fu::requires_functional_constructible<std::vector<int>>::type test_assert2;
|
// typedef fu::requires_functional_constructible<std::vector<int>>::type test_assert2;
|
||||||
|
|
||||||
detail::convert_void_to_continuable<void>::type* _test5 = nullptr;
|
// detail::convert_void_to_continuable<void>::type* _test5 = nullptr;
|
||||||
|
|
||||||
detail::convert_void_to_continuable<Continuable<Callback<SpellCastResult>>>::type* _test6 = nullptr;
|
// detail::convert_void_to_continuable<Continuable<Callback<SpellCastResult>>>::type* _test6 = nullptr;
|
||||||
|
|
||||||
// auto cba2 = make_continuable(myvec);
|
// auto cba2 = make_continuable(myvec);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user