Commit b82f6a80 authored by Dominik Charousset's avatar Dominik Charousset

Use id_block namespace instead of _type_ids suffix

parent 7b598dff
...@@ -324,15 +324,9 @@ behavior curl_master(stateful_actor<master_state>* self) { ...@@ -324,15 +324,9 @@ behavior curl_master(stateful_actor<master_state>* self) {
// signal handling for ctrl+c // signal handling for ctrl+c
std::atomic<bool> shutdown_flag{false}; std::atomic<bool> shutdown_flag{false};
struct config : actor_system_config {
config() {
init_global_meta_objects<curl_fuse_type_ids>();
}
};
} // namespace } // namespace
void caf_main(actor_system& system, const config&) { void caf_main(actor_system& system) {
// install signal handler // install signal handler
struct sigaction act; struct sigaction act;
act.sa_handler = [](int) { shutdown_flag = true; }; act.sa_handler = [](int) { shutdown_flag = true; };
...@@ -368,4 +362,4 @@ void caf_main(actor_system& system, const config&) { ...@@ -368,4 +362,4 @@ void caf_main(actor_system& system, const config&) {
curl_global_cleanup(); curl_global_cleanup();
} }
CAF_MAIN(io::middleman) CAF_MAIN(id_block::curl_fuse, io::middleman)
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
// Manual refs: 24-27, 30-34, 75-78, 81-84 (ConfiguringActorApplications) // Manual refs: 24-27, 30-34, 75-78, 81-84 (ConfiguringActorApplications)
// 23-33 (TypeInspection) // 23-33 (TypeInspection)
#include <string>
#include <vector>
#include <cassert> #include <cassert>
#include <utility>
#include <iostream> #include <iostream>
#include <string>
#include <utility>
#include <vector>
#include "caf/all.hpp" #include "caf/all.hpp"
...@@ -24,8 +24,8 @@ CAF_BEGIN_TYPE_ID_BLOCK(custom_types_1, first_custom_type_id) ...@@ -24,8 +24,8 @@ CAF_BEGIN_TYPE_ID_BLOCK(custom_types_1, first_custom_type_id)
CAF_END_TYPE_ID_BLOCK(custom_types_1) CAF_END_TYPE_ID_BLOCK(custom_types_1)
// --(rst-type-id-block-end)-- // --(rst-type-id-block-end)--
using std::cout;
using std::cerr; using std::cerr;
using std::cout;
using std::endl; using std::endl;
using std::vector; using std::vector;
...@@ -69,7 +69,7 @@ void testee(event_based_actor* self, size_t remaining) { ...@@ -69,7 +69,7 @@ void testee(event_based_actor* self, size_t remaining) {
else else
self->quit(); self->quit();
}; };
self->become ( self->become(
// note: we sent a foo_pair2, but match on foo_pair // note: we sent a foo_pair2, but match on foo_pair
// that works because both are aliases for std::pair<int, int> // that works because both are aliases for std::pair<int, int>
[=](const foo_pair& val) { [=](const foo_pair& val) {
...@@ -79,20 +79,10 @@ void testee(event_based_actor* self, size_t remaining) { ...@@ -79,20 +79,10 @@ void testee(event_based_actor* self, size_t remaining) {
[=](const foo& val) { [=](const foo& val) {
aout(self) << to_string(val) << endl; aout(self) << to_string(val) << endl;
set_next_behavior(); set_next_behavior();
} });
);
} }
// --(rst-config-begin)-- void caf_main(actor_system& sys) {
class config : public actor_system_config {
public:
config() {
init_global_meta_objects<custom_types_1_type_ids>();
}
};
// --(rst-config-end)--
void caf_main(actor_system& system, const config&) {
// two variables for testing serialization // two variables for testing serialization
foo2 f1; foo2 f1;
foo2 f2; foo2 f2;
...@@ -103,30 +93,28 @@ void caf_main(actor_system& system, const config&) { ...@@ -103,30 +93,28 @@ void caf_main(actor_system& system, const config&) {
// I/O buffer // I/O buffer
binary_serializer::container_type buf; binary_serializer::container_type buf;
// write f1 to buffer // write f1 to buffer
binary_serializer bs{system, buf}; binary_serializer bs{sys, buf};
auto e = bs(f1); auto e = bs(f1);
if (e) { if (e) {
std::cerr << "*** unable to serialize foo2: " std::cerr << "*** unable to serialize foo2: " << sys.render(e) << std::endl;
<< system.render(e) << std::endl;
return; return;
} }
// read f2 back from buffer // read f2 back from buffer
binary_deserializer bd{system, buf}; binary_deserializer bd{sys, buf};
e = bd(f2); e = bd(f2);
if (e) { if (e) {
std::cerr << "*** unable to serialize foo2: " std::cerr << "*** unable to serialize foo2: " << sys.render(e) << std::endl;
<< system.render(e) << std::endl;
return; return;
} }
// must be equal // must be equal
assert(to_string(f1) == to_string(f2)); assert(to_string(f1) == to_string(f2));
// spawn a testee that receives two messages of user-defined type // spawn a testee that receives two messages of user-defined type
auto t = system.spawn(testee, 2u); auto t = sys.spawn(testee, 2u);
scoped_actor self{system}; scoped_actor self{sys};
// send t a foo // send t a foo
self->send(t, foo{std::vector<int>{1, 2, 3, 4}, 5}); self->send(t, foo{std::vector<int>{1, 2, 3, 4}, 5});
// send t a foo_pair2 // send t a foo_pair2
self->send(t, foo_pair2{3, 4}); self->send(t, foo_pair2{3, 4});
} }
CAF_MAIN() CAF_MAIN(id_block::custom_types_1)
...@@ -64,15 +64,8 @@ behavior testee(event_based_actor* self) { ...@@ -64,15 +64,8 @@ behavior testee(event_based_actor* self) {
}; };
} }
class config : public actor_system_config { void caf_main(actor_system& sys) {
public: anon_send(sys.spawn(testee), foo{1, 2});
config() {
init_global_meta_objects<custom_types_2_type_ids>();
}
};
void caf_main(actor_system& system, const config&) {
anon_send(system.spawn(testee), foo{1, 2});
} }
CAF_MAIN() CAF_MAIN(id_block::custom_types_2)
...@@ -105,15 +105,8 @@ behavior testee(event_based_actor* self) { ...@@ -105,15 +105,8 @@ behavior testee(event_based_actor* self) {
}; };
} }
class config : public actor_system_config { void caf_main(actor_system& system) {
public:
config() {
init_global_meta_objects<custom_types_3_type_ids>();
}
};
void caf_main(actor_system& system, const config&) {
anon_send(system.spawn(testee), foo{1, 2}); anon_send(system.spawn(testee), foo{1, 2});
} }
CAF_MAIN() CAF_MAIN(id_block::custom_types_3)
...@@ -175,15 +175,9 @@ private: ...@@ -175,15 +175,9 @@ private:
behavior eating_; // wait for some time, then go thinking again behavior eating_; // wait for some time, then go thinking again
}; };
struct config : actor_system_config {
config() {
init_global_meta_objects<dining_philosophers_type_ids>();
}
};
} // namespace } // namespace
void caf_main(actor_system& system, const config&) { void caf_main(actor_system& system) {
scoped_actor self{system}; scoped_actor self{system};
// create five chopsticks // create five chopsticks
aout(self) << "chopstick ids are:"; aout(self) << "chopstick ids are:";
...@@ -200,4 +194,4 @@ void caf_main(actor_system& system, const config&) { ...@@ -200,4 +194,4 @@ void caf_main(actor_system& system, const config&) {
self->spawn<philosopher>(names[i], chopsticks[i], chopsticks[(i + 1) % 5]); self->spawn<philosopher>(names[i], chopsticks[i], chopsticks[(i + 1) % 5]);
} }
CAF_MAIN() CAF_MAIN(id_block::dining_philosophers)
...@@ -128,13 +128,7 @@ std::ostream& operator<<(std::ostream& out, const expected<int>& x) { ...@@ -128,13 +128,7 @@ std::ostream& operator<<(std::ostream& out, const expected<int>& x) {
return out << to_string(x.error()); return out << to_string(x.error());
} }
struct config : actor_system_config { void caf_main(actor_system& sys) {
config() {
init_global_meta_objects<fan_out_request_type_ids>();
}
};
void caf_main(actor_system& sys, const config&) {
// Spawn our matrix. // Spawn our matrix.
static constexpr int rows = 3; static constexpr int rows = 3;
static constexpr int columns = 6; static constexpr int columns = 6;
...@@ -164,4 +158,4 @@ void caf_main(actor_system& sys, const config&) { ...@@ -164,4 +158,4 @@ void caf_main(actor_system& sys, const config&) {
<< '\n'; << '\n';
} }
CAF_MAIN() CAF_MAIN(id_block::fan_out_request)
...@@ -73,12 +73,6 @@ private: ...@@ -73,12 +73,6 @@ private:
behavior empty_; behavior empty_;
}; };
struct config : actor_system_config {
config() {
init_global_meta_objects<fixed_stack_type_ids>();
}
};
void caf_main(actor_system& system) { void caf_main(actor_system& system) {
scoped_actor self{system}; scoped_actor self{system};
auto st = self->spawn<fixed_stack>(5u); auto st = self->spawn<fixed_stack>(5u);
...@@ -97,4 +91,4 @@ void caf_main(actor_system& system) { ...@@ -97,4 +91,4 @@ void caf_main(actor_system& system) {
self->send_exit(st, exit_reason::user_shutdown); self->send_exit(st, exit_reason::user_shutdown);
} }
CAF_MAIN() CAF_MAIN(id_block::fixed_stack)
...@@ -73,7 +73,6 @@ public: ...@@ -73,7 +73,6 @@ public:
bool server_mode = false; bool server_mode = false;
config() { config() {
init_global_meta_objects<group_chat_type_ids>();
opt_group{custom_options_, "global"} opt_group{custom_options_, "global"}
.add(name, "name,n", "set name") .add(name, "name,n", "set name")
.add(group_uris, "group,g", "join group") .add(group_uris, "group,g", "join group")
...@@ -162,4 +161,4 @@ void caf_main(actor_system& system, const config& cfg) { ...@@ -162,4 +161,4 @@ void caf_main(actor_system& system, const config& cfg) {
f(system, cfg); f(system, cfg);
} }
CAF_MAIN(io::middleman) CAF_MAIN(id_block::group_chat, io::middleman)
...@@ -102,7 +102,6 @@ void client_repl(function_view<calculator> f) { ...@@ -102,7 +102,6 @@ void client_repl(function_view<calculator> f) {
struct config : actor_system_config { struct config : actor_system_config {
config() { config() {
add_actor_type("calculator", calculator_fun); add_actor_type("calculator", calculator_fun);
init_global_meta_objects<remote_spawn_type_ids>();
opt_group{custom_options_, "global"} opt_group{custom_options_, "global"}
.add(port, "port,p", "set port") .add(port, "port,p", "set port")
.add(host, "host,H", "set node (ignored in server mode)") .add(host, "host,H", "set node (ignored in server mode)")
...@@ -153,4 +152,4 @@ void caf_main(actor_system& system, const config& cfg) { ...@@ -153,4 +152,4 @@ void caf_main(actor_system& system, const config& cfg) {
f(system, cfg); f(system, cfg);
} }
CAF_MAIN(io::middleman) CAF_MAIN(id_block::remote_spawn, io::middleman)
...@@ -126,7 +126,6 @@ behavior int_sink(event_based_actor* self) { ...@@ -126,7 +126,6 @@ behavior int_sink(event_based_actor* self) {
struct config : actor_system_config { struct config : actor_system_config {
config() { config() {
init_global_meta_objects<integer_stream_type_ids>();
opt_group{custom_options_, "global"} opt_group{custom_options_, "global"}
.add(with_stage, "with-stage,s", "use a stage for filtering odd numbers") .add(with_stage, "with-stage,s", "use a stage for filtering odd numbers")
.add(n, "num-values,n", "number of values produced by the source"); .add(n, "num-values,n", "number of values produced by the source");
...@@ -148,4 +147,4 @@ void caf_main(actor_system& sys, const config& cfg) { ...@@ -148,4 +147,4 @@ void caf_main(actor_system& sys, const config& cfg) {
} // namespace } // namespace
CAF_MAIN() CAF_MAIN(id_block::integer_stream)
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "caf/actor_system_config.hpp" #include "caf/actor_system_config.hpp"
#include "caf/detail/type_list.hpp" #include "caf/detail/type_list.hpp"
#include "caf/detail/type_traits.hpp" #include "caf/detail/type_traits.hpp"
#include "caf/init_global_meta_objects.hpp"
namespace caf { namespace caf {
...@@ -33,8 +34,8 @@ struct exec_main_helper<detail::type_list<actor_system&>> { ...@@ -33,8 +34,8 @@ struct exec_main_helper<detail::type_list<actor_system&>> {
using config = actor_system_config; using config = actor_system_config;
template <class F> template <class F>
void operator()(F& fun, actor_system& sys, config&) { auto operator()(F& fun, actor_system& sys, const config&) {
fun(sys); return fun(sys);
} }
}; };
...@@ -43,11 +44,30 @@ struct exec_main_helper<detail::type_list<actor_system&, const T&>> { ...@@ -43,11 +44,30 @@ struct exec_main_helper<detail::type_list<actor_system&, const T&>> {
using config = T; using config = T;
template <class F> template <class F>
void operator()(F& fun, actor_system& sys, config& cfg) { auto operator()(F& fun, actor_system& sys, const config& cfg) {
fun(sys, cfg); return fun(sys, cfg);
} }
}; };
template <class T>
void exec_main_init_meta_objects_single() {
if constexpr (std::is_base_of<actor_system::module, T>::value)
T::init_global_meta_objects();
else
init_global_meta_objects<T>();
}
template <class... Ts>
void exec_main_init_meta_objects() {
(exec_main_init_meta_objects_single<Ts>(), ...);
}
template <class T>
void exec_main_load_module(actor_system_config& cfg) {
if constexpr (std::is_base_of<actor_system::module, T>::value)
cfg.template load<T>();
}
template <class... Ts, class F = void (*)(actor_system&)> template <class... Ts, class F = void (*)(actor_system&)>
int exec_main(F fun, int argc, char** argv, int exec_main(F fun, int argc, char** argv,
const char* config_file_name = "caf-application.ini") { const char* config_file_name = "caf-application.ini") {
...@@ -80,8 +100,7 @@ int exec_main(F fun, int argc, char** argv, ...@@ -80,8 +100,7 @@ int exec_main(F fun, int argc, char** argv,
if (cfg.cli_helptext_printed) if (cfg.cli_helptext_printed)
return EXIT_SUCCESS; return EXIT_SUCCESS;
// Load modules. // Load modules.
std::initializer_list<unit_t> unused{unit_t{cfg.template load<Ts>()}...}; (exec_main_load_module<Ts>(cfg), ...);
CAF_IGNORE_UNUSED(unused);
// Initialize the actor system. // Initialize the actor system.
actor_system system{cfg}; actor_system system{cfg};
if (cfg.slave_mode) { if (cfg.slave_mode) {
...@@ -92,13 +111,20 @@ int exec_main(F fun, int argc, char** argv, ...@@ -92,13 +111,20 @@ int exec_main(F fun, int argc, char** argv,
return cfg.slave_mode_fun(system, cfg); return cfg.slave_mode_fun(system, cfg);
} }
helper f; helper f;
using result_type = decltype(f(fun, system, cfg));
if constexpr (std::is_convertible<result_type, int>::value) {
return f(fun, system, cfg);
} else {
f(fun, system, cfg); f(fun, system, cfg);
return EXIT_SUCCESS; return EXIT_SUCCESS;
}
} }
} // namespace caf } // namespace caf
#define CAF_MAIN(...) \ #define CAF_MAIN(...) \
int main(int argc, char** argv) { \ int main(int argc, char** argv) { \
return ::caf::exec_main<__VA_ARGS__>(caf_main, argc, argv); \ caf::exec_main_init_meta_objects<__VA_ARGS__>(); \
caf::core::init_global_meta_objects(); \
return caf::exec_main<__VA_ARGS__>(caf_main, argc, argv); \
} }
...@@ -52,8 +52,6 @@ template <class Range> ...@@ -52,8 +52,6 @@ template <class Range>
using make_type_id_sequence = typename type_id_sequence_helper< using make_type_id_sequence = typename type_id_sequence_helper<
type_id_pair<Range::begin, Range::end>>::type; type_id_pair<Range::begin, Range::end>>::type;
CAF_CORE_EXPORT void init_core_module_meta_objects();
} // namespace caf::detail } // namespace caf::detail
namespace caf { namespace caf {
...@@ -72,13 +70,17 @@ void init_global_meta_objects_impl(std::integer_sequence<uint16_t, Is...>) { ...@@ -72,13 +70,17 @@ void init_global_meta_objects_impl(std::integer_sequence<uint16_t, Is...>) {
/// Initializes the global meta object table with all types in `ProjectIds`. /// Initializes the global meta object table with all types in `ProjectIds`.
/// @warning calling this after constructing any ::actor_system is unsafe and /// @warning calling this after constructing any ::actor_system is unsafe and
/// causes undefined behavior. /// causes undefined behavior.
template <class ProjectIds = void> template <class ProjectIds>
void init_global_meta_objects() { void init_global_meta_objects() {
detail::init_core_module_meta_objects();
if constexpr (!std::is_same<ProjectIds, void>::value) {
detail::make_type_id_sequence<ProjectIds> seq; detail::make_type_id_sequence<ProjectIds> seq;
init_global_meta_objects_impl<ProjectIds>(seq); init_global_meta_objects_impl<ProjectIds>(seq);
}
} }
} // namespace caf } // namespace caf
namespace caf::core {
/// Initializes the meta objects of the core module.
CAF_CORE_EXPORT void init_global_meta_objects();
} // namespace caf::core
...@@ -86,14 +86,17 @@ constexpr type_id_t first_custom_type_id = 200; ...@@ -86,14 +86,17 @@ constexpr type_id_t first_custom_type_id = 200;
} // namespace caf } // namespace caf
/// Starts a code block for registering custom types to CAF. Stores the first ID /// Starts a code block for registering custom types to CAF. Stores the first ID
/// for the project as `caf::${project_name}_first_type_id`. Usually, users /// for the project as `caf::id_block::${project_name}_first_type_id`. Usually,
/// should use `caf::first_custom_type_id` as `first_id`. However, this /// users should use `caf::first_custom_type_id` as `first_id`. However, this
/// mechanism also enables modules to append IDs to a block of another module or /// mechanism also enables projects to append IDs to a block of another project.
/// module. If two modules are developed separately to avoid dependencies, they /// If two projects are developed separately to avoid dependencies, they only
/// only need to define sufficiently large offsets to guarantee collision-free /// need to define sufficiently large offsets to guarantee collision-free IDs.
/// IDs (CAF supports gaps in the ID space). /// CAF supports gaps in the ID space.
///
/// @note CAF reserves all names with the suffix `_module`. For example, core
/// module uses the project name `core_module`.
#define CAF_BEGIN_TYPE_ID_BLOCK(project_name, first_id) \ #define CAF_BEGIN_TYPE_ID_BLOCK(project_name, first_id) \
namespace caf { \ namespace caf::id_block { \
constexpr type_id_t project_name##_type_id_counter_init = __COUNTER__; \ constexpr type_id_t project_name##_type_id_counter_init = __COUNTER__; \
constexpr type_id_t project_name##_first_type_id = first_id; \ constexpr type_id_t project_name##_first_type_id = first_id; \
} }
...@@ -105,9 +108,9 @@ constexpr type_id_t first_custom_type_id = 200; ...@@ -105,9 +108,9 @@ constexpr type_id_t first_custom_type_id = 200;
template <> \ template <> \
struct type_id<CAF_PP_EXPAND fully_qualified_name> { \ struct type_id<CAF_PP_EXPAND fully_qualified_name> { \
static constexpr type_id_t value \ static constexpr type_id_t value \
= project_name##_first_type_id \ = id_block::project_name##_first_type_id \
+ (CAF_PP_CAT(CAF_PP_COUNTER, ()) \ + (CAF_PP_CAT(CAF_PP_COUNTER, ()) \
- project_name##_type_id_counter_init - 1); \ - id_block::project_name##_type_id_counter_init - 1); \
}; \ }; \
template <> \ template <> \
struct type_by_id<type_id<CAF_PP_EXPAND fully_qualified_name>::value> { \ struct type_by_id<type_id<CAF_PP_EXPAND fully_qualified_name>::value> { \
...@@ -128,8 +131,8 @@ constexpr type_id_t first_custom_type_id = 200; ...@@ -128,8 +131,8 @@ constexpr type_id_t first_custom_type_id = 200;
template <> \ template <> \
struct type_id<CAF_PP_EXPAND fully_qualified_name> { \ struct type_id<CAF_PP_EXPAND fully_qualified_name> { \
static constexpr type_id_t value \ static constexpr type_id_t value \
= project_name##_first_type_id \ = id_block::project_name##_first_type_id \
+ (__COUNTER__ - project_name##_type_id_counter_init - 1); \ + (__COUNTER__ - id_block::project_name##_type_id_counter_init - 1); \
}; \ }; \
template <> \ template <> \
struct type_by_id<type_id<CAF_PP_EXPAND fully_qualified_name>::value> { \ struct type_by_id<type_id<CAF_PP_EXPAND fully_qualified_name>::value> { \
...@@ -190,14 +193,16 @@ constexpr type_id_t first_custom_type_id = 200; ...@@ -190,14 +193,16 @@ constexpr type_id_t first_custom_type_id = 200;
CAF_PP_OVERLOAD(CAF_ADD_ATOM_, __VA_ARGS__)(__VA_ARGS__) CAF_PP_OVERLOAD(CAF_ADD_ATOM_, __VA_ARGS__)(__VA_ARGS__)
#endif #endif
/// Finalizes a code block for registering custom types to CAF. Stores the last /// Finalizes a code block for registering custom types to CAF. Defines a struct
/// type ID used by the project as `caf::${project_name}_last_type_id`. /// `caf::type_id::${project_name}` with two static members `begin` and `end`.
/// The former stores the first assigned type ID. The latter stores the last
/// assigned type ID + 1.
#define CAF_END_TYPE_ID_BLOCK(project_name) \ #define CAF_END_TYPE_ID_BLOCK(project_name) \
namespace caf { \ namespace caf::id_block { \
constexpr type_id_t project_name##_last_type_id \ constexpr type_id_t project_name##_last_type_id \
= project_name##_first_type_id \ = project_name##_first_type_id \
+ (__COUNTER__ - project_name##_type_id_counter_init - 2); \ + (__COUNTER__ - project_name##_type_id_counter_init - 2); \
struct project_name##_type_ids { \ struct project_name { \
static constexpr type_id_t begin = project_name##_first_type_id; \ static constexpr type_id_t begin = project_name##_first_type_id; \
static constexpr type_id_t end = project_name##_last_type_id + 1; \ static constexpr type_id_t end = project_name##_last_type_id + 1; \
}; \ }; \
...@@ -308,7 +313,7 @@ CAF_END_TYPE_ID_BLOCK(core_module) ...@@ -308,7 +313,7 @@ CAF_END_TYPE_ID_BLOCK(core_module)
namespace caf::detail { namespace caf::detail {
static constexpr type_id_t io_module_begin = core_module_type_ids::end; static constexpr type_id_t io_module_begin = id_block::core_module::end;
static constexpr type_id_t io_module_end = io_module_begin + 19; static constexpr type_id_t io_module_end = io_module_begin + 19;
......
...@@ -233,8 +233,8 @@ actor_system::actor_system(actor_system_config& cfg) ...@@ -233,8 +233,8 @@ actor_system::actor_system(actor_system_config& cfg)
} }
// Make sure meta objects are loaded. // Make sure meta objects are loaded.
auto gmos = detail::global_meta_objects(); auto gmos = detail::global_meta_objects();
if (gmos.size() < core_module_type_ids::end if (gmos.size() < id_block::core_module::end
|| gmos[core_module_type_ids::begin].type_name == nullptr) { || gmos[id_block::core_module::begin].type_name == nullptr) {
CAF_CRITICAL("actor_system created without calling " CAF_CRITICAL("actor_system created without calling "
"caf::init_global_meta_objects<>() before"); "caf::init_global_meta_objects<>() before");
} }
......
...@@ -36,11 +36,10 @@ ...@@ -36,11 +36,10 @@
#include "caf/upstream_msg.hpp" #include "caf/upstream_msg.hpp"
#include "caf/uri.hpp" #include "caf/uri.hpp"
namespace caf::detail { namespace caf::core {
void init_core_module_meta_objects() { void init_global_meta_objects() {
make_type_id_sequence<core_module_type_ids> seq; caf::init_global_meta_objects<id_block::core_module>();
init_global_meta_objects_impl<core_module_type_ids>(seq);
} }
} // namespace caf::detail } // namespace caf::core
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#include "core-test.hpp" #include "core-test.hpp"
int main(int argc, char** argv) { int main(int argc, char** argv) {
caf::init_global_meta_objects<caf::core_test_type_ids>(); using namespace caf;
return caf::test::main(argc, argv); init_global_meta_objects<id_block::core_test>();
core::init_global_meta_objects();
return test::main(argc, argv);
} }
...@@ -80,13 +80,13 @@ CAF_TEST(meta objects allow serialization of objects) { ...@@ -80,13 +80,13 @@ CAF_TEST(meta objects allow serialization of objects) {
CAF_TEST(init_global_meta_objects takes care of creating a meta object table) { CAF_TEST(init_global_meta_objects takes care of creating a meta object table) {
auto xs = global_meta_objects(); auto xs = global_meta_objects();
CAF_REQUIRE_EQUAL(xs.size(), caf::core_test_last_type_id + 1u); CAF_REQUIRE_EQUAL(xs.size(), caf::id_block::core_test::end);
CAF_CHECK_EQUAL(type_name_by_id_v<type_id_v<i32_wrapper>>, "i32_wrapper"s); CAF_CHECK_EQUAL(type_name_by_id_v<type_id_v<i32_wrapper>>, "i32_wrapper"s);
CAF_CHECK_EQUAL(type_name_by_id_v<type_id_v<i64_wrapper>>, "i64_wrapper"s); CAF_CHECK_EQUAL(type_name_by_id_v<type_id_v<i64_wrapper>>, "i64_wrapper"s);
CAF_CHECK_EQUAL(xs[type_id_v<i32_wrapper>].type_name, "i32_wrapper"s); CAF_CHECK_EQUAL(xs[type_id_v<i32_wrapper>].type_name, "i32_wrapper"s);
CAF_CHECK_EQUAL(xs[type_id_v<i64_wrapper>].type_name, "i64_wrapper"s); CAF_CHECK_EQUAL(xs[type_id_v<i64_wrapper>].type_name, "i64_wrapper"s);
CAF_MESSAGE("calling init_global_meta_objects again is a no-op"); CAF_MESSAGE("calling init_global_meta_objects again is a no-op");
init_global_meta_objects<core_test_type_ids>(); init_global_meta_objects<id_block::core_test>();
auto ys = global_meta_objects(); auto ys = global_meta_objects();
auto same = [](const auto& x, const auto& y) { auto same = [](const auto& x, const auto& y) {
return x.type_name == y.type_name; return x.type_name == y.type_name;
......
...@@ -118,4 +118,4 @@ CAF_END_TYPE_ID_BLOCK(io_module) ...@@ -118,4 +118,4 @@ CAF_END_TYPE_ID_BLOCK(io_module)
CAF_ALLOW_UNSAFE_MESSAGE_TYPE(caf::io::doorman_ptr) CAF_ALLOW_UNSAFE_MESSAGE_TYPE(caf::io::doorman_ptr)
CAF_ALLOW_UNSAFE_MESSAGE_TYPE(caf::io::scribe_ptr) CAF_ALLOW_UNSAFE_MESSAGE_TYPE(caf::io::scribe_ptr)
static_assert(caf::io_module_type_ids::end == caf::detail::io_module_end); static_assert(caf::id_block::io_module::end == caf::detail::io_module_end);
...@@ -83,7 +83,7 @@ private: ...@@ -83,7 +83,7 @@ private:
} // namespace } // namespace
void middleman::init_global_meta_objects() { void middleman::init_global_meta_objects() {
caf::init_global_meta_objects<io_module_type_ids>(); caf::init_global_meta_objects<id_block::io_module>();
} }
actor_system::module* middleman::make(actor_system& sys, detail::type_list<>) { actor_system::module* middleman::make(actor_system& sys, detail::type_list<>) {
......
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
#include "io-test.hpp" #include "io-test.hpp"
int main(int argc, char** argv) { int main(int argc, char** argv) {
caf::init_global_meta_objects<caf::io_test_type_ids>(); using namespace caf;
caf::io::middleman::init_global_meta_objects(); init_global_meta_objects<id_block::io_test>();
return caf::test::main(argc, argv); io::middleman::init_global_meta_objects();
core::init_global_meta_objects();
return test::main(argc, argv);
} }
...@@ -7,7 +7,9 @@ ...@@ -7,7 +7,9 @@
#include "caf/io/middleman.hpp" #include "caf/io/middleman.hpp"
int main(int argc, char** argv) { int main(int argc, char** argv) {
caf::init_global_meta_objects<caf::openssl_test_type_ids>(); using namespace caf;
caf::io::middleman::init_global_meta_objects(); init_global_meta_objects<id_block::openssl_test>();
return caf::test::main(argc, argv); io::middleman::init_global_meta_objects();
core::init_global_meta_objects();
return test::main(argc, argv);
} }
...@@ -30,34 +30,54 @@ The compiler expands this example code to the following. ...@@ -30,34 +30,54 @@ The compiler expands this example code to the following.
return exec_main<io::middleman>(caf_main, argc, argv); return exec_main<io::middleman>(caf_main, argc, argv);
} }
The function ``exec_main`` creates a config object, loads all modules The function ``exec_main`` performs several steps:
requested in ``CAF_MAIN`` and then calls ``caf_main``. A
minimal implementation for ``main`` performing all these steps manually #. Initialize all meta objects for the type ID blocks listed in ``CAF_MAIN``.
is shown in the next example for the sake of completeness. #. Create a config object. If ``caf_main`` has two arguments, then CAF
assumes that the second argument is the configuration and the type gets
derived from that argument. Otherwise, CAF uses ``actor_system_config``.
#. Parse command line arguments and configuration file.
#. Load all modules requested in ``CAF_MAIN``.
#. Create an actor system.
#. Call ``caf_main`` with the actor system and optionally with ``config``.
When implementing the steps performed by ``CAF_MAIN`` by hand, the ``main``
function would resemble the following (pseudo) code:
.. code-block:: C++ .. code-block:: C++
int main(int argc, char** argv) { int main(int argc, char** argv) {
// Initialze the global type information before anything else.
init_global_meta_objects<...>();
core::init_global_meta_objects();
// Create the config.
actor_system_config cfg; actor_system_config cfg;
// read CLI options // Read CLI options.
cfg.parse(argc, argv); cfg.parse(argc, argv);
// return immediately if a help text was printed // Return immediately if a help text was printed.
if (cfg.cli_helptext_printed) if (cfg.cli_helptext_printed)
return 0; return 0;
// load modules // Load modules.
cfg.load<io::middleman>(); cfg.load<...>();
// create actor system and call caf_main // Create the actor system.
actor_system system{cfg}; actor_system sys{cfg};
caf_main(system); // Run user-defined code.
caf_main(sys, cfg);
} }
However, setting up config objects by hand is usually not necessary. CAF Using ``CAF_MAIN`` simply automates that boilerplate code. A minimal example
automatically selects user-defined subclasses of with a custom type ID block as well as a custom configuration class with the I/O
``actor_system_config`` if ``caf_main`` takes a second module loaded looks as follows:
parameter by reference, as shown in the minimal example below.
.. code-block:: C++ .. code-block:: C++
CAF_BEGIN_TYPE_ID_BLOCK(my, first_custom_type_id)
// ...
CAF_END_TYPE_ID_BLOCK(my)
class my_config : public actor_system_config { class my_config : public actor_system_config {
public: public:
my_config() { my_config() {
...@@ -69,10 +89,7 @@ parameter by reference, as shown in the minimal example below. ...@@ -69,10 +89,7 @@ parameter by reference, as shown in the minimal example below.
// ... // ...
} }
CAF_MAIN() CAF_MAIN(id_block::my, io::middleman)
Users can perform additional initialization, add custom program options, etc.
simply by implementing a default constructor.
.. _system-config-module: .. _system-config-module:
...@@ -215,12 +232,9 @@ By assigning type IDs and providing ``inspect`` overloads, we provide static and ...@@ -215,12 +232,9 @@ By assigning type IDs and providing ``inspect`` overloads, we provide static and
compile-time information for all our types. However, CAF also needs some compile-time information for all our types. However, CAF also needs some
information at run-time for deserializing received data. The function information at run-time for deserializing received data. The function
``init_global_meta_objects`` takes care fo registering all the state we need at ``init_global_meta_objects`` takes care fo registering all the state we need at
run-time. run-time. This function usually gets called by ``CAF_MAIN`` automatically. When
not using this macro, users **must** call ``init_global_meta_objects`` before
.. literalinclude:: /examples/custom_type/custom_types_1.cpp any other CAF function.
:language: C++
:start-after: --(rst-config-begin)--
:end-before: --(rst-config-end)--
Adding Custom Error Types Adding Custom Error Types
------------------------- -------------------------
......
...@@ -749,7 +749,6 @@ struct config : public actor_system_config { ...@@ -749,7 +749,6 @@ struct config : public actor_system_config {
bool include_hidden_actors = false; bool include_hidden_actors = false;
size_t verbosity = 0; size_t verbosity = 0;
config() { config() {
init_global_meta_objects<caf_vec_type_ids>();
opt_group{custom_options_, "global"} opt_group{custom_options_, "global"}
.add(output_file, "output-file,o", "Path for the output file") .add(output_file, "output-file,o", "Path for the output file")
.add(include_hidden_actors, "include-hidden-actors,i", .add(include_hidden_actors, "include-hidden-actors,i",
...@@ -881,5 +880,4 @@ void caf_main(actor_system& sys, const config& cfg) { ...@@ -881,5 +880,4 @@ void caf_main(actor_system& sys, const config& cfg) {
} // namespace } // namespace
CAF_MAIN() CAF_MAIN(id_block::caf_vec)
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