Commit 1e23f322 authored by Dominik Charousset's avatar Dominik Charousset

Allow actor to define a custom name

parent 528285ba
...@@ -462,6 +462,31 @@ struct is_optional<optional<T>> : std::true_type { ...@@ -462,6 +462,31 @@ struct is_optional<optional<T>> : std::true_type {
// no members // no members
}; };
// Checks whether T has a member variable named `name`.
template <class T>
class has_name {
private:
// a simple struct with a member called `name`
struct fallback {
int name;
};
// creates an ambiguity for any `T` with the requested member
struct derived : T, fallback {
// no members
};
// picked for any U without requested member since `U::name` is not ambigious
template <class U>
static char fun(U*, decltype(U::name)* = nullptr);
// picked for any U with requested member since `U::name` is ambigious
static int fun(void*);
public:
static constexpr bool value = sizeof(fun(static_cast<derived*>(nullptr))) > 1;
};
} // namespace detail } // namespace detail
} // namespace caf } // namespace caf
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <type_traits> #include <type_traits>
#include "caf/fwd.hpp" #include "caf/fwd.hpp"
#include "caf/detail/type_traits.hpp"
namespace caf { namespace caf {
namespace experimental { namespace experimental {
...@@ -50,6 +51,10 @@ public: ...@@ -50,6 +51,10 @@ public:
state_.~State(); state_.~State();
} }
const char* name() const override final {
return get_name(state_);
}
/// A reference to the actor's state. /// A reference to the actor's state.
State& state; State& state;
...@@ -75,6 +80,27 @@ private: ...@@ -75,6 +80,27 @@ private:
new (&state_) State(); new (&state_) State();
} }
static const char* unbox_str(const char* str) {
return str;
}
template <class U>
static const char* unbox_str(const U& str) {
return str.c_str();
}
template <class U>
typename std::enable_if<detail::has_name<U>::value, const char*>::type
get_name(const U& st) const {
return unbox_str(st.name);
}
template <class U>
typename std::enable_if<! detail::has_name<U>::value, const char*>::type
get_name(const U&) const {
return Base::name();
}
union { State state_; }; union { State state_; };
}; };
......
...@@ -387,6 +387,11 @@ public: ...@@ -387,6 +387,11 @@ public:
attach(attachable_ptr{new functor_attachable(std::move(f))}); attach(attachable_ptr{new functor_attachable(std::move(f))});
} }
/// Returns an implementation-dependent name for logging purposes, which
/// is only valid as long as the actor is running. The default
/// implementation simply returns "actor".
virtual const char* name() const;
/**************************************************************************** /****************************************************************************
* deprecated member functions * * deprecated member functions *
****************************************************************************/ ****************************************************************************/
......
...@@ -820,6 +820,10 @@ response_promise local_actor::make_response_promise() { ...@@ -820,6 +820,10 @@ response_promise local_actor::make_response_promise() {
return result; return result;
} }
const char* local_actor::name() const {
return "actor";
}
behavior& local_actor::get_behavior() { behavior& local_actor::get_behavior() {
return pending_responses_.empty() ? bhvr_stack_.back() return pending_responses_.empty() ? bhvr_stack_.back()
: pending_responses_.front().second; : pending_responses_.front().second;
......
...@@ -98,6 +98,22 @@ void test_adder(ActorUnderTest aut) { ...@@ -98,6 +98,22 @@ void test_adder(ActorUnderTest aut) {
anon_send_exit(aut, exit_reason::kill); anon_send_exit(aut, exit_reason::kill);
} }
template <class State>
void test_name(const char* expected) {
auto aut = spawn([](stateful_actor<State>* self) -> behavior {
return [=](get_atom) {
self->quit();
return self->name();
};
});
scoped_actor self;
self->sync_send(aut, get_atom::value).await(
[&](const string& str) {
CAF_CHECK_EQUAL(str, expected);
}
);
}
} // namespace <anonymous> } // namespace <anonymous>
CAF_TEST_FIXTURE_SCOPE(dynamic_stateful_actor_tests, fixture) CAF_TEST_FIXTURE_SCOPE(dynamic_stateful_actor_tests, fixture)
...@@ -118,4 +134,25 @@ CAF_TEST(typed_stateful_actor_class) { ...@@ -118,4 +134,25 @@ CAF_TEST(typed_stateful_actor_class) {
test_adder(spawn_typed<typed_adder_class>()); test_adder(spawn_typed<typed_adder_class>());
} }
CAF_TEST(no_name) {
struct state {
// empty
};
test_name<state>("actor");
}
CAF_TEST(char_name) {
struct state {
const char* name = "testee";
};
test_name<state>("testee");
}
CAF_TEST(string_name) {
struct state {
string name = "testee2";
};
test_name<state>("testee2");
}
CAF_TEST_FIXTURE_SCOPE_END() CAF_TEST_FIXTURE_SCOPE_END()
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