// Copyright Sebastian Jeckel 2014. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #pragma once #include "react/detail/Defs.h" #include "react/detail/ReactiveDomain.h" /*****************************************/ REACT_BEGIN /*****************************************/ /////////////////////////////////////////////////////////////////////////////////////////////////// /// ReactiveObject /////////////////////////////////////////////////////////////////////////////////////////////////// template class ReactiveObject { public: /////////////////////////////////////////////////////////////////////////////////////////////////// /// Aliases /////////////////////////////////////////////////////////////////////////////////////////////////// using DomainT = D; template using SignalT = Signal; template using VarSignalT = VarSignal; template using RefSignalT = RefSignal; template using VarRefSignalT = VarRefSignal; template using EventsT = Events; template using EventSourceT = EventSource; using ObserverT = Observer; using ReactiveLoopT = ReactiveLoop; /////////////////////////////////////////////////////////////////////////////////////////////////// /// MakeVar /////////////////////////////////////////////////////////////////////////////////////////////////// template < typename V, typename S = std::decay::type, class = std::enable_if< !IsSignal::value>::type > static auto MakeVar(V&& value) -> VarSignalT { return REACT::MakeVar(std::forward(value)); } ////////////////////////////////////////////////////////////////////////////////////////////////////////// // MakeVar (higher order) ////////////////////////////////////////////////////////////////////////////////////////////////////////// template < typename V, typename S = std::decay::type, typename TInner = S::ValueT, class = std::enable_if< IsSignal::value>::type > static auto MakeVar(V&& value) -> VarSignalT> { return REACT::MakeVar(std::forward(value)); } /////////////////////////////////////////////////////////////////////////////////////////////////// /// MakeSignal /////////////////////////////////////////////////////////////////////////////////////////////////// template < typename F, typename ... TArgs > static auto MakeSignal(F&& func, const SignalT& ... args) -> SignalT::type> { using S = typename std::result_of::type; return REACT::MakeSignal(std::forward(func), args ...); } /////////////////////////////////////////////////////////////////////////////////////////////////// /// MakeEventSource /////////////////////////////////////////////////////////////////////////////////////////////////// template static auto MakeEventSource() -> EventSourceT { return REACT::MakeEventSource(); } /////////////////////////////////////////////////////////////////////////////////////////////////// /// Flatten macros /////////////////////////////////////////////////////////////////////////////////////////////////// // Todo: Add safety wrapper + static assert to check for this for ReactiveObject // Note: Using static_cast rather than -> return type, because when using lambda for inline class // initialization, decltype did not recognize the parameter r #define REACTIVE_REF(obj, name) \ Flatten( \ MakeSignal( \ [] (REACT_IMPL::Identity::Type::ValueT::type r) \ { \ return static_cast::Type>(r.name); \ }, \ obj)) #define REACTIVE_PTR(obj, name) \ Flatten( \ MakeSignal( \ [] (REACT_IMPL::Identity::Type::ValueT r) \ { \ REACT_ASSERT(r != nullptr); \ return static_castname)>::Type>(r->name); \ }, \ obj)) }; /******************************************/ REACT_END /******************************************/