Commit 85a4fc8d authored by Dominik Charousset's avatar Dominik Charousset

maintenance & documentation

parent 7e757380
...@@ -126,24 +126,33 @@ add_custom_target(uninstall ...@@ -126,24 +126,33 @@ add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P COMMAND ${CMAKE_COMMAND} -P
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
set (CPPA_BINARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)
set (CPPA_LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/lib)
if (LIBRARY_OUTPUT_PATH)
set (CPPA_LIBRARY_OUTPUT_PATH ${LIBRARY_OUTPUT_PATH})
set (CPPA_LIBRARY_PATH ${LIBRARY_OUTPUT_PATH})
else()
set (CPPA_LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/lib)
set (CPPA_LIBRARY_PATH ${CPPA_LIBRARY_OUTPUT_PATH})
set (LIBRARY_OUTPUT_PATH ${CPPA_LIBRARY_OUTPUT_PATH} CACHE PATH "Single directory for all libraries")
endif()
# setting path to cppa headers and libcppa # setting path to cppa headers and libcppa
set (CPPA_INCLUDE_PATH ${CMAKE_SOURCE_DIR}/libcppa) set (CPPA_INCLUDE_PATH ${CMAKE_SOURCE_DIR}/libcppa)
set (CPPA_LIBRARY_PATH ${CPPA_LIBRARY_OUTPUT_PATH})
set (CPPA_INCLUDE ${CPPA_INCLUDE_PATH}) set (CPPA_INCLUDE ${CPPA_INCLUDE_PATH})
if (APPLE) if (APPLE)
set (CPPA_LIBRARY ${CPPA_LIBRARY_PATH}/libcppa.dylib) set (CPPA_LIBRARY ${LIBRARY_OUTPUT_PATH}/libcppa.dylib)
elseif (UNIX) elseif (UNIX)
set (CPPA_LIBRARY ${CPPA_LIBRARY_PATH}/libcppa.so) set (CPPA_LIBRARY ${LIBRARY_OUTPUT_PATH}/libcppa.so)
else () else ()
message (SEND_FATAL "Host platform not supported ...") message (SEND_FATAL "Host platform not supported ...")
endif () endif ()
set (LIBRARY_OUTPUT_PATH ${CPPA_LIBRARY_OUTPUT_PATH} if (EXECUTABLE_OUTPUT_PATH)
CACHE PATH "Single directory for all libraries") else ()
set (EXECUTABLE_OUTPUT_PATH ${CPPA_BINARY_OUTPUT_PATH} set (EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin CACHE PATH "Single directory for all executables")
CACHE PATH "Single directory for all executables") endif ()
add_subdirectory(unit_testing) add_subdirectory(unit_testing)
add_subdirectory(examples) add_subdirectory(examples)
......
...@@ -45,6 +45,7 @@ else (CPPA_LIBRARY AND CPPA_INCLUDE) ...@@ -45,6 +45,7 @@ else (CPPA_LIBRARY AND CPPA_INCLUDE)
${CPPA_LIBRARY_PATH}/.libs ${CPPA_LIBRARY_PATH}/.libs
${CMAKE_LIBRARY_PATH} ${CMAKE_LIBRARY_PATH}
${CMAKE_INSTALL_PREFIX}/lib ${CMAKE_INSTALL_PREFIX}/lib
${LIBRARY_OUTPUT_PATH}
) )
if (CPPA_LIBRARY) if (CPPA_LIBRARY)
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#ifndef CPPA_ABSTRACT_EVENT_BASED_ACTOR_HPP #ifndef CPPA_ABSTRACT_EVENT_BASED_ACTOR_HPP
#define CPPA_ABSTRACT_EVENT_BASED_ACTOR_HPP #define CPPA_ABSTRACT_EVENT_BASED_ACTOR_HPP
#include <tuple>
#include <stack> #include <stack>
#include <memory> #include <memory>
#include <vector> #include <vector>
......
...@@ -189,6 +189,9 @@ class local_actor : public actor { ...@@ -189,6 +189,9 @@ class local_actor : public actor {
do_become(bhvr, false, true); do_become(bhvr, false, true);
} }
/**
* @brief Sets the actor's behavior.
*/
inline void become(discard_behavior_t, behavior&& bhvr) { inline void become(discard_behavior_t, behavior&& bhvr) {
do_become(new behavior(std::move(bhvr)), true, true); do_become(new behavior(std::move(bhvr)), true, true);
} }
...@@ -206,10 +209,16 @@ class local_actor : public actor { ...@@ -206,10 +209,16 @@ class local_actor : public actor {
do_become(bhvr, false, false); do_become(bhvr, false, false);
} }
/**
* @brief Sets the actor's behavior.
*/
inline void become(keep_behavior_t, behavior&& bhvr) { inline void become(keep_behavior_t, behavior&& bhvr) {
do_become(new behavior(std::move(bhvr)), true, false); do_become(new behavior(std::move(bhvr)), true, false);
} }
/**
* @brief Sets the actor's behavior.
*/
inline void become(behavior&& bhvr) { inline void become(behavior&& bhvr) {
become(discard_behavior, std::move(bhvr)); become(discard_behavior, std::move(bhvr));
} }
...@@ -237,21 +246,25 @@ class local_actor : public actor { ...@@ -237,21 +246,25 @@ class local_actor : public actor {
become(keep_behavior, match_expr_concat(std::move(arg0), std::forward<Args>(args)...)); become(keep_behavior, match_expr_concat(std::move(arg0), std::forward<Args>(args)...));
} }
/**
* @brief Sets the actor's behavior.
*/
template<typename... Cases, typename... Args> template<typename... Cases, typename... Args>
inline void become(match_expr<Cases...> arg0, Args&&... args) { inline void become(match_expr<Cases...> arg0, Args&&... args) {
become(discard_behavior, match_expr_concat(std::move(arg0), std::forward<Args>(args)...)); become(discard_behavior, match_expr_concat(std::move(arg0), std::forward<Args>(args)...));
} }
/** /**
* @brief Returns to a previous behavior or finishes execution * @brief Returns to a previous behavior if available.
* if no previous behavior is available.
*/ */
virtual void unbecome() = 0; virtual void unbecome() = 0;
/** /**
* @brief Can be overridden to initialize an actor before any * @brief Can be overridden to initialize an actor before any
* message is handled. * message is handled.
* @warning Must not call blocking functions. * @warning Must not call blocking functions such as
* {@link cppa::receive receive}.
* @note Calling {@link become} to set an initial behavior is supported.
*/ */
virtual void init(); virtual void init();
......
...@@ -586,10 +586,6 @@ struct mexpr_fwd { ...@@ -586,10 +586,6 @@ struct mexpr_fwd {
namespace cppa { namespace cppa {
/**
* @brief A function that works on the projection of given data rather than
* on the data itself.
*/
template<class... Cases> template<class... Cases>
class match_expr { class match_expr {
......
...@@ -79,10 +79,13 @@ class thread_mapped_actor : public local_actor { ...@@ -79,10 +79,13 @@ class thread_mapped_actor : public local_actor {
#else // CPPA_DOCUMENTATION #else // CPPA_DOCUMENTATION
class self_type;
class thread_mapped_actor : public detail::stacked_actor_mixin< class thread_mapped_actor : public detail::stacked_actor_mixin<
thread_mapped_actor, thread_mapped_actor,
detail::abstract_actor<local_actor> > { detail::abstract_actor<local_actor> > {
friend class self_type; // needs access to cleanup()
friend class detail::receive_policy; friend class detail::receive_policy;
typedef detail::stacked_actor_mixin< typedef detail::stacked_actor_mixin<
......
...@@ -45,6 +45,7 @@ else (CPPA_LIBRARY AND CPPA_INCLUDE) ...@@ -45,6 +45,7 @@ else (CPPA_LIBRARY AND CPPA_INCLUDE)
${CPPA_LIBRARY_PATH}/.libs ${CPPA_LIBRARY_PATH}/.libs
${CMAKE_LIBRARY_PATH} ${CMAKE_LIBRARY_PATH}
${CMAKE_INSTALL_PREFIX}/lib ${CMAKE_INSTALL_PREFIX}/lib
${LIBRARY_OUTPUT_PATH}
) )
if (CPPA_LIBRARY) if (CPPA_LIBRARY)
......
...@@ -774,8 +774,7 @@ bool announce(const std::type_info& tinfo, uniform_type_info* utype) { ...@@ -774,8 +774,7 @@ bool announce(const std::type_info& tinfo, uniform_type_info* utype) {
return uti_map().insert({ raw_name(tinfo) }, utype); return uti_map().insert({ raw_name(tinfo) }, utype);
} }
uniform_type_info::uniform_type_info(const std::string& uname) : m_name(uname) { uniform_type_info::uniform_type_info(const std::string& str) : m_name(str) { }
}
uniform_type_info::~uniform_type_info() { uniform_type_info::~uniform_type_info() {
} }
......
...@@ -45,6 +45,7 @@ else (CPPA_LIBRARY AND CPPA_INCLUDE) ...@@ -45,6 +45,7 @@ else (CPPA_LIBRARY AND CPPA_INCLUDE)
${CPPA_LIBRARY_PATH}/.libs ${CPPA_LIBRARY_PATH}/.libs
${CMAKE_LIBRARY_PATH} ${CMAKE_LIBRARY_PATH}
${CMAKE_INSTALL_PREFIX}/lib ${CMAKE_INSTALL_PREFIX}/lib
${LIBRARY_OUTPUT_PATH}
) )
if (CPPA_LIBRARY) if (CPPA_LIBRARY)
......
...@@ -326,25 +326,17 @@ auto actor_prototype(const Args&... args) -> actor_template<decltype(mexpr_conca ...@@ -326,25 +326,17 @@ auto actor_prototype(const Args&... args) -> actor_template<decltype(mexpr_conca
return {mexpr_concat(args...)}; return {mexpr_concat(args...)};
} }
class actor_factory {
public:
virtual ~actor_factory() { }
virtual actor_ptr spawn() = 0;
};
template<typename InitFun, typename CleanupFun, typename... Members> template<typename InitFun, typename CleanupFun, typename... Members>
class simple_event_based_actor_impl : public event_based_actor { class simple_event_based_actor_impl : public event_based_actor {
public: public:
simple_event_based_actor_impl(InitFun fun, CleanupFun cfun) template<typename... Args>
: m_init(std::move(fun)), m_cleanup(std::move(cfun)) { } simple_event_based_actor_impl(InitFun fun, CleanupFun cfun, Args&&... args)
: m_init(std::move(fun)), m_cleanup(std::move(cfun))
, m_members(std::forward<Args>(args)...) { }
void init() { apply(); } void init() { apply(m_init); }
void on_exit() { m_cleanup(); } void on_exit() { m_cleanup(); }
...@@ -352,53 +344,74 @@ class simple_event_based_actor_impl : public event_based_actor { ...@@ -352,53 +344,74 @@ class simple_event_based_actor_impl : public event_based_actor {
InitFun m_init; InitFun m_init;
CleanupFun m_cleanup; CleanupFun m_cleanup;
std::tuple<Members...> m_members; detail::tdata<Members...> m_members;
void apply(typename std::add_pointer<Members>::type... args) { template<typename F>
m_init(args...); void apply(F& f, typename std::add_pointer<Members>::type... args) {
f(args...);
} }
template<typename... Args> template<typename F, typename... Args>
void apply(Args... args) { void apply(F& f, Args... args) {
apply(args..., &std::get<sizeof...(Args)>(m_members)); apply(f, args..., &get_ref<sizeof...(Args)>(m_members));
} }
}; };
template<typename InitFun, typename... Members> template<typename InitFun, typename CleanupFun, typename... Members>
class actor_tpl : public actor_factory { class simple_event_based_actor_factory {
InitFun m_init_fun;
public: public:
actor_tpl(InitFun fun) : m_init_fun(std::move(fun)) { } typedef simple_event_based_actor_impl<InitFun, CleanupFun, Members...> impl;
actor_ptr spawn() { simple_event_based_actor_factory(InitFun fun, CleanupFun cfun)
auto void_fun = []() { }; : m_init(std::move(fun)), m_cleanup(std::move(cfun)) { }
return cppa::spawn(new simple_event_based_actor_impl<InitFun, decltype(void_fun), Members...>(m_init_fun, void_fun));
template<typename... Args>
actor_ptr spawn(Args&&... args) {
return cppa::spawn(new impl(m_init, m_cleanup, std::forward<Args>(args)...));
} }
private:
InitFun m_init;
CleanupFun m_cleanup;
}; };
template<typename InitFun, class TypeList> template<typename InitFun, typename CleanupFun, class TypeList>
struct actor_tpl_from_type_list; struct actor_tpl_from_type_list;
template<typename InitFun, typename... Ts> template<typename InitFun, typename CleanupFun, typename... Ts>
struct actor_tpl_from_type_list<InitFun, util::type_list<Ts...> > { struct actor_tpl_from_type_list<InitFun, CleanupFun, util::type_list<Ts...> > {
typedef actor_tpl<InitFun, Ts...> type; typedef simple_event_based_actor_factory<InitFun, CleanupFun, Ts...> type;
}; };
template<typename Fun> template<typename Init, typename Cleanup>
std::unique_ptr<actor_factory> foobaz(Fun fun) { struct actor_tpl_from_fun {
typedef typename util::get_callable_trait<Fun>::type ctrait; typedef typename util::get_arg_types<Init>::types arg_types;
typedef typename ctrait::arg_types arg_types; typedef typename util::get_arg_types<Cleanup>::types arg_types2;
static_assert(util::tl_forall<arg_types, std::is_pointer>::value, static_assert(util::tl_forall<arg_types, std::is_pointer>::value,
"Functor takes non-pointer arguments"); "First functor takes non-pointer arguments");
static_assert( std::is_same<arg_types, arg_types2>::value
|| std::is_same<util::type_list<>, arg_types2>::value,
"Second functor must provide either the same signature "
" as the first one or take zero arguments");
typedef typename util::tl_map<arg_types, std::remove_pointer>::type mems; typedef typename util::tl_map<arg_types, std::remove_pointer>::type mems;
typedef typename actor_tpl_from_type_list<Fun, mems>::type tpl_type; typedef typename actor_tpl_from_type_list<Init, Cleanup, mems>::type type;
return std::unique_ptr<actor_factory>{new tpl_type(fun)}; };
}
void dummy_function() { }
struct factory {
template<typename Fun>
static inline typename actor_tpl_from_fun<Fun, void (*)()>::type event_based(Fun fun) {
return {std::move(fun), dummy_function};
}
};
size_t test__spawn() { size_t test__spawn() {
using std::string; using std::string;
...@@ -421,14 +434,6 @@ size_t test__spawn() { ...@@ -421,14 +434,6 @@ size_t test__spawn() {
); );
CPPA_IF_VERBOSE(cout << "ok" << endl); CPPA_IF_VERBOSE(cout << "ok" << endl);
/*
auto mirror = actor_prototype (
others() >> []() {
self->last_sender() << self->last_dequeued();
}
).spawn();
*/
CPPA_IF_VERBOSE(cout << "test echo actor ... " << std::flush); CPPA_IF_VERBOSE(cout << "test echo actor ... " << std::flush);
auto mecho = spawn(echo_actor); auto mecho = spawn(echo_actor);
send(mecho, "hello echo"); send(mecho, "hello echo");
...@@ -498,8 +503,8 @@ size_t test__spawn() { ...@@ -498,8 +503,8 @@ size_t test__spawn() {
await_all_others_done(); await_all_others_done();
CPPA_IF_VERBOSE(cout << "ok" << endl); CPPA_IF_VERBOSE(cout << "ok" << endl);
CPPA_IF_VERBOSE(cout << "test factory ... " << std::flush); CPPA_IF_VERBOSE(cout << "test event-based factory ... " << std::flush);
auto factory = foobaz([&](int* i, float*, std::string*) { auto factory = factory::event_based([&](int* i, float*, std::string*) {
self->become ( self->become (
on(atom("get_int")) >> [i]() { on(atom("get_int")) >> [i]() {
reply(*i); reply(*i);
...@@ -512,10 +517,16 @@ size_t test__spawn() { ...@@ -512,10 +517,16 @@ size_t test__spawn() {
} }
); );
}); });
auto foobaz_actor = factory->spawn(); auto foobaz_actor = factory.spawn(23);
send(foobaz_actor, atom("get_int"));
send(foobaz_actor, atom("set_int"), 42); send(foobaz_actor, atom("set_int"), 42);
send(foobaz_actor, atom("get_int")); send(foobaz_actor, atom("get_int"));
send(foobaz_actor, atom("done")); send(foobaz_actor, atom("done"));
receive (
on_arg_match >> [&](int value) {
CPPA_CHECK_EQUAL(23, value);
}
);
receive ( receive (
on_arg_match >> [&](int value) { on_arg_match >> [&](int value) {
CPPA_CHECK_EQUAL(42, value); CPPA_CHECK_EQUAL(42, value);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment