/* * This file is part of aasdk library project. * Copyright (C) 2018 f1x.studio (Michal Szwaj) * * aasdk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * aasdk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with aasdk. If not, see . */ #pragma once #include #include #include #include #include namespace f1x { namespace aasdk { namespace io { template class Promise: boost::noncopyable { public: typedef ResolveArgumentType ValueType; typedef ErrorArgumentType ErrorType; typedef std::function ResolveHandler; typedef std::function RejectHandler; typedef std::shared_ptr Pointer; static Pointer defer(boost::asio::io_service& ioService) { return std::make_shared(ioService); } static Pointer defer(boost::asio::io_service::strand& strand) { return std::make_shared(strand); } Promise(boost::asio::io_service& ioService) : ioContextWrapper_(ioService) { } Promise(boost::asio::io_service::strand& strand) : ioContextWrapper_(strand) { } void then(ResolveHandler resolveHandler, RejectHandler rejectHandler = RejectHandler()) { std::lock_guard lock(mutex_); resolveHandler_ = std::move(resolveHandler); rejectHandler_ = std::move(rejectHandler); } void resolve(ResolveArgumentType argument) { std::lock_guard lock(mutex_); if(resolveHandler_ != nullptr && this->isPending()) { ioContextWrapper_.post([argument = std::move(argument), resolveHandler = std::move(resolveHandler_)]() mutable { resolveHandler(std::move(argument)); }); } ioContextWrapper_.reset(); rejectHandler_ = RejectHandler(); } void reject(ErrorArgumentType error) { std::lock_guard lock(mutex_); if(rejectHandler_ != nullptr && this->isPending()) { ioContextWrapper_.post([error = std::move(error), rejectHandler = std::move(rejectHandler_)]() mutable { rejectHandler(std::move(error)); }); } ioContextWrapper_.reset(); resolveHandler_ = ResolveHandler(); } private: bool isPending() const { return ioContextWrapper_.isActive(); } ResolveHandler resolveHandler_; RejectHandler rejectHandler_; IOContextWrapper ioContextWrapper_; std::mutex mutex_; }; template class Promise: boost::noncopyable { public: typedef ErrorArgumentType ErrorType; typedef std::function ResolveHandler; typedef std::function RejectHandler; typedef std::shared_ptr Pointer; static Pointer defer(boost::asio::io_service& ioService) { return std::make_shared(ioService); } static Pointer defer(boost::asio::io_service::strand& strand) { return std::make_shared(strand); } Promise(boost::asio::io_service& ioService) : ioContextWrapper_(ioService) { } Promise(boost::asio::io_service::strand& strand) : ioContextWrapper_(strand) { } void then(ResolveHandler resolveHandler, RejectHandler rejectHandler = RejectHandler()) { std::lock_guard lock(mutex_); resolveHandler_ = std::move(resolveHandler); rejectHandler_ = std::move(rejectHandler); } void resolve() { std::lock_guard lock(mutex_); if(resolveHandler_ != nullptr && this->isPending()) { ioContextWrapper_.post([resolveHandler = std::move(resolveHandler_)]() mutable { resolveHandler(); }); } ioContextWrapper_.reset(); rejectHandler_ = RejectHandler(); } void reject(ErrorArgumentType error) { std::lock_guard lock(mutex_); if(rejectHandler_ != nullptr && this->isPending()) { ioContextWrapper_.post([error = std::move(error), rejectHandler = std::move(rejectHandler_)]() mutable { rejectHandler(std::move(error)); }); } ioContextWrapper_.reset(); resolveHandler_ = ResolveHandler(); } private: bool isPending() const { return ioContextWrapper_.isActive(); } ResolveHandler resolveHandler_; RejectHandler rejectHandler_; IOContextWrapper ioContextWrapper_; std::mutex mutex_; }; template<> class Promise: boost::noncopyable { public: typedef std::function ResolveHandler; typedef std::function RejectHandler; typedef std::shared_ptr Pointer; static Pointer defer(boost::asio::io_service& ioService) { return std::make_shared(ioService); } static Pointer defer(boost::asio::io_service::strand& strand) { return std::make_shared(strand); } Promise(boost::asio::io_service& ioService) : ioContextWrapper_(ioService) { } Promise(boost::asio::io_service::strand& strand) : ioContextWrapper_(strand) { } void then(ResolveHandler resolveHandler, RejectHandler rejectHandler = RejectHandler()) { std::lock_guard lock(mutex_); resolveHandler_ = std::move(resolveHandler); rejectHandler_ = std::move(rejectHandler); } void resolve() { std::lock_guard lock(mutex_); if(resolveHandler_ != nullptr && this->isPending()) { ioContextWrapper_.post([resolveHandler = std::move(resolveHandler_)]() mutable { resolveHandler(); }); } ioContextWrapper_.reset(); rejectHandler_ = RejectHandler(); } void reject() { std::lock_guard lock(mutex_); if(rejectHandler_ != nullptr && this->isPending()) { ioContextWrapper_.post([rejectHandler = std::move(rejectHandler_)]() mutable { rejectHandler(); }); } ioContextWrapper_.reset(); resolveHandler_ = ResolveHandler(); } private: bool isPending() const { return ioContextWrapper_.isActive(); } ResolveHandler resolveHandler_; RejectHandler rejectHandler_; IOContextWrapper ioContextWrapper_; std::mutex mutex_; }; template class Promise: boost::noncopyable { public: typedef ResolveArgumentType ValueType; typedef std::function ResolveHandler; typedef std::function RejectHandler; typedef std::shared_ptr Pointer; static Pointer defer(boost::asio::io_service& ioService) { return std::make_shared(ioService); } static Pointer defer(boost::asio::io_service::strand& strand) { return std::make_shared(strand); } Promise(boost::asio::io_service& ioService) : ioContextWrapper_(ioService) { } Promise(boost::asio::io_service::strand& strand) : ioContextWrapper_(strand) { } void then(ResolveHandler resolveHandler, RejectHandler rejectHandler = RejectHandler()) { std::lock_guard lock(mutex_); resolveHandler_ = std::move(resolveHandler); rejectHandler_ = std::move(rejectHandler); } void resolve(ResolveArgumentType argument) { std::lock_guard lock(mutex_); if(resolveHandler_ != nullptr && this->isPending()) { ioContextWrapper_.post([argument = std::move(argument), resolveHandler = std::move(resolveHandler_)]() mutable { resolveHandler(std::move(argument)); }); } ioContextWrapper_.reset(); rejectHandler_ = RejectHandler(); } void reject() { std::lock_guard lock(mutex_); if(rejectHandler_ != nullptr && this->isPending()) { ioContextWrapper_.post([rejectHandler = std::move(rejectHandler_)]() mutable { rejectHandler(); }); } ioContextWrapper_.reset(); resolveHandler_ = ResolveHandler(); } private: bool isPending() const { return ioContextWrapper_.isActive(); } ResolveHandler resolveHandler_; RejectHandler rejectHandler_; IOContextWrapper ioContextWrapper_; std::mutex mutex_; }; } } }