#include "Callback.h" #include "WeakCallbackContainer.h" #include "Continuable.h" #include #include #include #include #include #include #include enum SpellCastResult { SPELL_FAILED_SUCCESS = 0, SPELL_FAILED_AFFECTING_COMBAT = 1, SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 2, SPELL_FAILED_ALREADY_AT_FULL_MANA = 3, SPELL_FAILED_ALREADY_AT_FULL_POWER = 4, SPELL_FAILED_ALREADY_BEING_TAMED = 5 }; template using Optional = boost::optional; // Original method taking an optional callback. void CastSpell(int id, Optional> const& callback = boost::none) { std::cout << "Casting " << id << std::endl; // on success call the callback with SPELL_FAILED_SUCCESS if (callback) (*callback)(SPELL_FAILED_SUCCESS); } // Promise wrapped callback decorator. Continuable CastSpellPromise(int id) { return make_continuable([=](Callback&& callback) { CastSpell(id, callback); }); } // Void instant returning continuable promise for testing purposes Continuable<> TrivialPromise(std::string const& msg = "") { return make_continuable([=](Callback<>&& callback) { if (!msg.empty()) std::cout << msg << std::endl; callback(); }); } Continuable Validate() { return make_continuable([=](Callback&& callback) { std::cout << "Validate " << std::endl; callback(true); }); } template void test_unwrap(std::string const& msg) { std::cout << msg << " is unwrappable: " << (fu::is_unwrappable::value ? "true" : "false") << std::endl; } int main(int /*argc*/, char** /*argv*/) { CastSpellPromise(1) .then([](SpellCastResult) { return CastSpellPromise(2); }) .then([](SpellCastResult) { std::cout << "Pause a callback (void test) " << std::endl; }) .then(CastSpellPromise(3)) .then(CastSpellPromise(4)) .then(CastSpellPromise(5)) .then([](SpellCastResult) { return Validate(); }); // Mockup of aggregate methods make_continuable() .all( [] { return TrivialPromise(); }, [] { return TrivialPromise(); }, [] { return TrivialPromise(); } ) .some(2, // Only 2 of 3 must complete [] { return TrivialPromise(); }, [] { return TrivialPromise(); }, [] { return TrivialPromise(); } ) .any( // Any of 2. [] { return TrivialPromise(); }, [] { return TrivialPromise(); } ) .then([] { }); //Continuable cb = make_continuable([](Callback&& callback) //{ // callback(true); //}); //test_unwrap("void()"); //test_unwrap>("std::function"); //test_unwrap>("std::vector"); //make_continuable([=](Callback<>&&) //{ //}); //int i = 0; //++i; //auto lam = [=](Callback&&) //{ // // on success call the callback with SPELL_FAILED_SUCCESS // // callback(SPELL_FAILED_SUCCESS); //}; //fu::function_type_of_t fun1; //fun1 = lam; //fun1(Callback()); //fu::function_type_of_t> fun2; // //shared_callback_of_t> sc1; //weak_callback_of_t> sc2; // //make_weak_wrapped_callback(sc1); //make_weak_wrapped_callback(sc2); //WeakCallbackContainer callback; // //auto weakCallback = callback([] //{ //}); //typedef Continuable cont123; //typedef Continuable myty1; //typedef Continuable myty2; //// Convertible test // //// Continuable> spell //{ // auto stack = // int iii = 0; // iii = 1; //} //std::vector myvec; //typedef fu::requires_functional_constructible>::type test_assert1; //// typedef fu::requires_functional_constructible>::type test_assert2; //// Brainstorming: this shows an example callback chain //// Given by continuable //std::function&&)> continuable_1 = [](Callback&& callback) //{ // callback(SPELL_FAILED_AFFECTING_COMBAT); //}; //// Implemented by user //std::function&&)>(SpellCastResult)> callback_by_user_1 = [](SpellCastResult) //{ // // Given by continuable // // Fn2 // return [](Callback&& callback) // { // callback(true); // }; //}; //// Implemented by user //std::function&&)>(bool)> cn2 = [](bool val) //{ // // Finished // std::cout << "Callback chain finished! -> " << val << std::endl; // // Given by continuable (auto end) // return [](Callback<>&&) // { // // Empty callback // }; //}; //// Entry point //std::function&&>)> entry = [continuable_1 /*= move*/, callback_by_user_1 /*given by the user (::then(...))*/] // (std::function&&)>) //{ // // Call with auto created wrapper by the continuable // continuable_1([&](SpellCastResult result /*forward args*/) // { // // Wrapper functional to process unary or multiple promised callbacks // // Returned from the user // std::function&&)> fn2 = callback_by_user_1(/*forward args*/ result); // return std::move(fn2); // }); //}; //// Here we go //entry(); std::cout << "ok" << std::endl; return 0; }