Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
71c043cc
Commit
71c043cc
authored
Feb 24, 2020
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Migrate to the new messaging API
parent
77569942
Changes
46
Show whitespace changes
Inline
Side-by-side
Showing
46 changed files
with
404 additions
and
299 deletions
+404
-299
CMakeLists.txt
CMakeLists.txt
+9
-45
examples/curl/curl_fuse.cpp
examples/curl/curl_fuse.cpp
+13
-11
examples/custom_type/custom_types_1.cpp
examples/custom_type/custom_types_1.cpp
+19
-9
examples/custom_type/custom_types_2.cpp
examples/custom_type/custom_types_2.cpp
+9
-5
examples/custom_type/custom_types_3.cpp
examples/custom_type/custom_types_3.cpp
+34
-33
examples/dynamic_behavior/dining_philosophers.cpp
examples/dynamic_behavior/dining_philosophers.cpp
+10
-8
examples/message_passing/fan_out_request.cpp
examples/message_passing/fan_out_request.cpp
+10
-6
examples/message_passing/fixed_stack.cpp
examples/message_passing/fixed_stack.cpp
+13
-11
examples/remoting/distributed_calculator.cpp
examples/remoting/distributed_calculator.cpp
+2
-1
examples/remoting/group_chat.cpp
examples/remoting/group_chat.cpp
+56
-55
examples/remoting/remote_spawn.cpp
examples/remoting/remote_spawn.cpp
+15
-10
examples/streaming/integer_stream.cpp
examples/streaming/integer_stream.cpp
+26
-12
libcaf_core/CMakeLists.txt
libcaf_core/CMakeLists.txt
+1
-0
libcaf_core/caf/binary_deserializer.hpp
libcaf_core/caf/binary_deserializer.hpp
+1
-1
libcaf_core/caf/binary_serializer.hpp
libcaf_core/caf/binary_serializer.hpp
+1
-1
libcaf_core/caf/deserializer.hpp
libcaf_core/caf/deserializer.hpp
+1
-2
libcaf_core/caf/detail/append_hex.hpp
libcaf_core/caf/detail/append_hex.hpp
+4
-4
libcaf_core/caf/detail/make_meta_object.hpp
libcaf_core/caf/detail/make_meta_object.hpp
+5
-0
libcaf_core/caf/detail/message_builder_element.hpp
libcaf_core/caf/detail/message_builder_element.hpp
+1
-1
libcaf_core/caf/detail/message_data.hpp
libcaf_core/caf/detail/message_data.hpp
+1
-1
libcaf_core/caf/detail/meta_object.hpp
libcaf_core/caf/detail/meta_object.hpp
+4
-1
libcaf_core/caf/detail/serialized_size.hpp
libcaf_core/caf/detail/serialized_size.hpp
+1
-1
libcaf_core/caf/detail/stringification_inspector.hpp
libcaf_core/caf/detail/stringification_inspector.hpp
+1
-1
libcaf_core/caf/detail/type_id_list_builder.hpp
libcaf_core/caf/detail/type_id_list_builder.hpp
+2
-1
libcaf_core/caf/intrusive_ptr.hpp
libcaf_core/caf/intrusive_ptr.hpp
+1
-1
libcaf_core/caf/message.hpp
libcaf_core/caf/message.hpp
+4
-3
libcaf_core/caf/message_builder.hpp
libcaf_core/caf/message_builder.hpp
+3
-2
libcaf_core/caf/serializer.hpp
libcaf_core/caf/serializer.hpp
+1
-1
libcaf_core/caf/type_id.hpp
libcaf_core/caf/type_id.hpp
+28
-1
libcaf_core/caf/type_id_list.hpp
libcaf_core/caf/type_id_list.hpp
+8
-5
libcaf_core/src/binary_deserializer.cpp
libcaf_core/src/binary_deserializer.cpp
+2
-8
libcaf_core/src/binary_serializer.cpp
libcaf_core/src/binary_serializer.cpp
+2
-4
libcaf_core/src/detail/append_hex.cpp
libcaf_core/src/detail/append_hex.cpp
+3
-3
libcaf_core/src/detail/append_percent_encoded.cpp
libcaf_core/src/detail/append_percent_encoded.cpp
+3
-2
libcaf_core/src/detail/meta_object.cpp
libcaf_core/src/detail/meta_object.cpp
+3
-2
libcaf_core/src/detail/serialized_size.cpp
libcaf_core/src/detail/serialized_size.cpp
+2
-5
libcaf_core/src/inbound_path.cpp
libcaf_core/src/inbound_path.cpp
+1
-1
libcaf_core/src/message.cpp
libcaf_core/src/message.cpp
+22
-3
libcaf_core/src/type_id_list.cpp
libcaf_core/src/type_id_list.cpp
+2
-2
libcaf_core/test/detail/meta_object.cpp
libcaf_core/test/detail/meta_object.cpp
+3
-3
libcaf_core/test/message.cpp
libcaf_core/test/message.cpp
+21
-2
manual/ConfiguringActorApplications.rst
manual/ConfiguringActorApplications.rst
+27
-20
manual/RemoteSpawn.rst
manual/RemoteSpawn.rst
+2
-1
manual/Streaming.rst
manual/Streaming.rst
+8
-4
manual/TypeInspection.rst
manual/TypeInspection.rst
+7
-6
tools/caf-vec.cpp
tools/caf-vec.cpp
+12
-0
No files found.
CMakeLists.txt
View file @
71c043cc
...
@@ -403,50 +403,29 @@ if(NOT APPLE AND NOT WIN32)
...
@@ -403,50 +403,29 @@ if(NOT APPLE AND NOT WIN32)
endif
()
endif
()
# -fPIC generates warnings on MinGW and Cygwin plus extra setup steps needed on MinGW
# -fPIC generates warnings on MinGW and Cygwin plus extra setup steps needed on MinGW
if
(
MINGW
)
if
(
MINGW
)
add_definitions
(
-D_WIN32_WINNT=0x0600
)
add_definitions
(
-D_WIN32_WINNT=0x0600 -DWIN32
)
add_definitions
(
-DWIN32
)
list
(
APPEND CAF_EXTRA_LDFLAGS -lws2_32 -liphlpapi -lpsapi
)
list
(
APPEND CAF_EXTRA_LDFLAGS -lws2_32 -liphlpapi -lpsapi
)
# build static to avoid runtime dependencies to GCC libraries
# build static to avoid runtime dependencies to GCC libraries
build_string
(
"EXTRA_FLAGS"
"-static"
)
add_compile_options
(
-static
)
elseif
(
CYGWIN
)
elseif
(
CYGWIN
)
build_string
(
"EXTRA_FLAGS"
"-U__STRICT_ANSI__"
)
add_compile_options
(
-U__STRICT_ANSI__
)
endif
()
endif
()
if
(
WIN32
)
if
(
WIN32
)
list
(
APPEND CAF_EXTRA_LDFLAGS ws2_32 iphlpapi
)
list
(
APPEND CAF_EXTRA_LDFLAGS ws2_32 iphlpapi
)
endif
()
endif
()
# iOS support
# iOS support
if
(
CAF_OSX_SYSROOT
)
if
(
CAF_OSX_SYSROOT
)
set
(
CMAKE_OSX_SYSROOT
"
${
CAF_OSX_SYSROOT
}
"
)
set
(
CMAKE_OSX_SYSROOT
"
${
CAF_OSX_SYSROOT
}
"
)
endif
()
endif
()
if
(
CAF_IOS_DEPLOYMENT_TARGET
)
if
(
CAF_IOS_DEPLOYMENT_TARGET
)
if
(
CAF_OSX_SYSROOT STREQUAL
"iphonesimulator"
)
if
(
CAF_OSX_SYSROOT STREQUAL
"iphonesimulator"
)
build_string
(
"EXTRA_FLAGS"
add_compile_options
(
"-mios-simulator-version-min=
${
CAF_IOS_DEPLOYMENT_TARGET
}
"
)
"-mios-simulator-version-min=
${
CAF_IOS_DEPLOYMENT_TARGET
}
"
)
else
()
else
()
build_string
(
"EXTRA_FLAGS"
add_compile_options
(
"-miphoneos-version-min=
${
CAF_IOS_DEPLOYMENT_TARGET
}
"
)
"-miphoneos-version-min=
${
CAF_IOS_DEPLOYMENT_TARGET
}
"
)
endif
()
endif
()
endif
()
endif
()
# check if the user provided CXXFLAGS, set defaults otherwise
if
(
NOT CMAKE_CXX_FLAGS
)
set
(
CMAKE_CXX_FLAGS
"-Wextra -Wall -pedantic
${
EXTRA_FLAGS
}
"
)
endif
()
if
(
NOT CMAKE_CXX_FLAGS_DEBUG
)
set
(
CMAKE_CXX_FLAGS_DEBUG
"-O0 -g"
)
endif
()
if
(
NOT CMAKE_CXX_FLAGS_MINSIZEREL
)
set
(
CMAKE_CXX_FLAGS_MINSIZEREL
"-Os"
)
endif
()
if
(
NOT CMAKE_CXX_FLAGS_RELEASE
)
set
(
CMAKE_CXX_FLAGS_RELEASE
"-O3 -DNDEBUG"
)
endif
()
if
(
NOT CMAKE_CXX_FLAGS_RELWITHDEBINFO
)
set
(
CMAKE_CXX_FLAGS_RELWITHDEBINFO
"-O2 -g -fno-omit-frame-pointer"
)
endif
()
# set build default build type to RelWithDebInfo if not set
if
(
NOT CMAKE_BUILD_TYPE
)
set
(
CMAKE_BUILD_TYPE RelWithDebInfo
)
endif
()
# needed by subprojects
# needed by subprojects
if
(
DEFINED CMAKE_LD_LIBS
)
if
(
DEFINED CMAKE_LD_LIBS
)
list
(
APPEND
${
CMAKE_LD_LIBS
}
)
list
(
APPEND
${
CMAKE_LD_LIBS
}
)
...
@@ -616,17 +595,6 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/CAFConfig.cmake"
...
@@ -616,17 +595,6 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/CAFConfig.cmake"
"
${
CMAKE_CURRENT_BINARY_DIR
}
/CAFConfigVersion.cmake"
"
${
CMAKE_CURRENT_BINARY_DIR
}
/CAFConfigVersion.cmake"
DESTINATION
"
${
INSTALL_CAF_CMAKEDIR
}
"
)
DESTINATION
"
${
INSTALL_CAF_CMAKEDIR
}
"
)
# -- Fetch branch name and SHA if available ------------------------------------
if
(
EXISTS
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/release.txt"
)
file
(
READ
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/release.txt"
CAF_RELEASE
)
string
(
REGEX REPLACE
"
\n
"
""
CAF_RELEASE
"
${
CAF_RELEASE
}
"
)
else
()
set
(
CAF_RELEASE
"
${
CAF_VERSION
}
"
)
endif
()
message
(
STATUS
"Set release version for all documentation to
${
CAF_RELEASE
}
."
)
# -- Setup for building manual and API documentation ---------------------------
# -- Setup for building manual and API documentation ---------------------------
if
(
NOT WIN32
)
if
(
NOT WIN32
)
...
@@ -661,11 +629,7 @@ invertYesNo(CAF_NO_EXCEPTIONS CAF_BUILD_WITH_EXCEPTIONS)
...
@@ -661,11 +629,7 @@ invertYesNo(CAF_NO_EXCEPTIONS CAF_BUILD_WITH_EXCEPTIONS)
invertYesNo
(
CAF_NO_MEM_MANAGEMENT CAF_BUILD_MEM_MANAGEMENT
)
invertYesNo
(
CAF_NO_MEM_MANAGEMENT CAF_BUILD_MEM_MANAGEMENT
)
invertYesNo
(
CAF_NO_OPENSSL CAF_BUILD_OPENSSL
)
invertYesNo
(
CAF_NO_OPENSSL CAF_BUILD_OPENSSL
)
invertYesNo
(
CAF_NO_PYTHON CAF_BUILD_PYTHON
)
invertYesNo
(
CAF_NO_PYTHON CAF_BUILD_PYTHON
)
# collect all compiler flags
get_property
(
all_cxx_flags DIRECTORY PROPERTY COMPILE_OPTIONS
)
string
(
TOUPPER
"
${
CMAKE_BUILD_TYPE
}
"
UPPER_BUILD_TYPE
)
set
(
ALL_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
${
CMAKE_CXX_FLAGS_
${
UPPER_BUILD_TYPE
}}
"
)
set
(
ALL_LD_FLAGS
"
${
CMAKE_SHARED_LINKER_FLAGS
}
${
CAF_EXTRA_LDFLAGS
}
"
)
string
(
STRIP
"
${
ALL_LD_FLAGS
}
"
ALL_LD_FLAGS
)
# done
# done
if
(
NOT CAF_NO_SUMMARY
)
if
(
NOT CAF_NO_SUMMARY
)
message
(
STATUS
message
(
STATUS
...
@@ -689,7 +653,7 @@ if(NOT CAF_NO_SUMMARY)
...
@@ -689,7 +653,7 @@ if(NOT CAF_NO_SUMMARY)
"
\n
Build Python:
${
CAF_BUILD_PYTHON
}
"
"
\n
Build Python:
${
CAF_BUILD_PYTHON
}
"
"
\n
"
"
\n
"
"
\n
CXX:
${
CMAKE_CXX_COMPILER
}
"
"
\n
CXX:
${
CMAKE_CXX_COMPILER
}
"
"
\n
CXXFLAGS:
${
ALL_CXX_FLAGS
}
"
"
\n
CXXFLAGS:
${
all_cxx_flags
}
"
"
\n
LINKER_FLAGS (shared)
${
ALL_LD_FLAGS
}
"
"
\n
LINKER_FLAGS (shared)
${
ALL_LD_FLAGS
}
"
"
\n
"
"
\n
"
"
\n
Source directory:
${
CMAKE_CURRENT_SOURCE_DIR
}
"
"
\n
Source directory:
${
CMAKE_CURRENT_SOURCE_DIR
}
"
...
...
examples/curl/curl_fuse.cpp
View file @
71c043cc
...
@@ -56,16 +56,22 @@ CAF_POP_WARNINGS
...
@@ -56,16 +56,22 @@ CAF_POP_WARNINGS
# pragma clang diagnostic ignored "-Wunused-const-variable"
# pragma clang diagnostic ignored "-Wunused-const-variable"
#endif // __clang__
#endif // __clang__
CAF_BEGIN_TYPE_ID_BLOCK
(
curl_fuse
,
first_custom_type_id
)
CAF_ADD_TYPE_ID
(
curl_fuse
,
std
::
vector
<
char
>
)
CAF_ADD_ATOM
(
curl_fuse
,
read_atom
);
CAF_ADD_ATOM
(
curl_fuse
,
fail_atom
);
CAF_ADD_ATOM
(
curl_fuse
,
next_atom
);
CAF_ADD_ATOM
(
curl_fuse
,
reply_atom
);
CAF_ADD_ATOM
(
curl_fuse
,
finished_atom
);
CAF_END_TYPE_ID_BLOCK
(
curl_fuse
)
using
namespace
caf
;
using
namespace
caf
;
using
buffer_type
=
std
::
vector
<
char
>
;
using
buffer_type
=
std
::
vector
<
char
>
;
CAF_MSG_TYPE_ADD_ATOM
(
read_atom
);
CAF_MSG_TYPE_ADD_ATOM
(
fail_atom
);
CAF_MSG_TYPE_ADD_ATOM
(
next_atom
);
CAF_MSG_TYPE_ADD_ATOM
(
reply_atom
);
CAF_MSG_TYPE_ADD_ATOM
(
finished_atom
);
namespace
color
{
namespace
color
{
// UNIX terminal color codes
// UNIX terminal color codes
...
@@ -320,11 +326,7 @@ std::atomic<bool> shutdown_flag{false};
...
@@ -320,11 +326,7 @@ std::atomic<bool> shutdown_flag{false};
struct
config
:
actor_system_config
{
struct
config
:
actor_system_config
{
config
()
{
config
()
{
add_message_type
<
read_atom
>
(
"read_atom"
);
init_global_meta_objects
<
curl_fuse_type_ids
>
();
add_message_type
<
fail_atom
>
(
"fail_atom"
);
add_message_type
<
next_atom
>
(
"next_atom"
);
add_message_type
<
reply_atom
>
(
"reply_atom"
);
add_message_type
<
finished_atom
>
(
"finished_atom"
);
}
}
};
};
...
...
examples/custom_type/custom_types_1.cpp
View file @
71c043cc
...
@@ -11,6 +11,20 @@
...
@@ -11,6 +11,20 @@
#include "caf/all.hpp"
#include "caf/all.hpp"
// --(rst-type-id-block-begin)--
struct
foo
;
struct
foo2
;
CAF_BEGIN_TYPE_ID_BLOCK
(
custom_types_1
,
first_custom_type_id
)
CAF_ADD_TYPE_ID
(
custom_types_1
,
foo
)
CAF_ADD_TYPE_ID
(
custom_types_1
,
foo2
)
CAF_ADD_TYPE_ID
(
custom_types_1
,
std
::
pair
<
int32_t
CAF_PP_COMMA
int32_t
>
)
CAF_END_TYPE_ID_BLOCK
(
custom_types_1
)
// --(rst-type-id-block-end)--
using
std
::
cout
;
using
std
::
cout
;
using
std
::
cerr
;
using
std
::
cerr
;
using
std
::
endl
;
using
std
::
endl
;
...
@@ -18,19 +32,17 @@ using std::vector;
...
@@ -18,19 +32,17 @@ using std::vector;
using
namespace
caf
;
using
namespace
caf
;
namespace
{
// --(rst-foo-begin)--
// POD struct foo
struct
foo
{
struct
foo
{
std
::
vector
<
int
>
a
;
std
::
vector
<
int
>
a
;
int
b
;
int
b
;
};
};
// foo needs to be serializable
template
<
class
Inspector
>
template
<
class
Inspector
>
typename
Inspector
::
result_type
inspect
(
Inspector
&
f
,
foo
&
x
)
{
typename
Inspector
::
result_type
inspect
(
Inspector
&
f
,
foo
&
x
)
{
return
f
(
meta
::
type_name
(
"foo"
),
x
.
a
,
x
.
b
);
return
f
(
meta
::
type_name
(
"foo"
),
x
.
a
,
x
.
b
);
}
}
// --(rst-foo-end)--
// a pair of two ints
// a pair of two ints
using
foo_pair
=
std
::
pair
<
int
,
int
>
;
using
foo_pair
=
std
::
pair
<
int
,
int
>
;
...
@@ -72,14 +84,14 @@ void testee(event_based_actor* self, size_t remaining) {
...
@@ -72,14 +84,14 @@ void testee(event_based_actor* self, size_t remaining) {
);
);
}
}
// --(rst-config-begin)--
class
config
:
public
actor_system_config
{
class
config
:
public
actor_system_config
{
public:
public:
config
()
{
config
()
{
add_message_type
<
foo
>
(
"foo"
);
init_global_meta_objects
<
custom_types_1_type_ids
>
();
add_message_type
<
foo2
>
(
"foo2"
);
add_message_type
<
foo_pair
>
(
"foo_pair"
);
}
}
};
};
// --(rst-config-end)--
void
caf_main
(
actor_system
&
system
,
const
config
&
)
{
void
caf_main
(
actor_system
&
system
,
const
config
&
)
{
// two variables for testing serialization
// two variables for testing serialization
...
@@ -118,6 +130,4 @@ void caf_main(actor_system& system, const config&) {
...
@@ -118,6 +130,4 @@ void caf_main(actor_system& system, const config&) {
self
->
send
(
t
,
foo_pair2
{
3
,
4
});
self
->
send
(
t
,
foo_pair2
{
3
,
4
});
}
}
}
// namespace
CAF_MAIN
()
CAF_MAIN
()
examples/custom_type/custom_types_2.cpp
View file @
71c043cc
...
@@ -6,14 +6,20 @@
...
@@ -6,14 +6,20 @@
#include "caf/all.hpp"
#include "caf/all.hpp"
class
foo
;
CAF_BEGIN_TYPE_ID_BLOCK
(
custom_types_2
,
first_custom_type_id
)
CAF_ADD_TYPE_ID
(
custom_types_2
,
foo
)
CAF_END_TYPE_ID_BLOCK
(
custom_types_2
)
using
std
::
cout
;
using
std
::
cout
;
using
std
::
endl
;
using
std
::
endl
;
using
std
::
make_pair
;
using
std
::
make_pair
;
using
namespace
caf
;
using
namespace
caf
;
namespace
{
// a simple class using getter and setter member functions
// a simple class using getter and setter member functions
class
foo
{
class
foo
{
public:
public:
...
@@ -61,7 +67,7 @@ behavior testee(event_based_actor* self) {
...
@@ -61,7 +67,7 @@ behavior testee(event_based_actor* self) {
class
config
:
public
actor_system_config
{
class
config
:
public
actor_system_config
{
public:
public:
config
()
{
config
()
{
add_message_type
<
foo
>
(
"foo"
);
init_global_meta_objects
<
custom_types_2_type_ids
>
(
);
}
}
};
};
...
@@ -69,6 +75,4 @@ void caf_main(actor_system& system, const config&) {
...
@@ -69,6 +75,4 @@ void caf_main(actor_system& system, const config&) {
anon_send
(
system
.
spawn
(
testee
),
foo
{
1
,
2
});
anon_send
(
system
.
spawn
(
testee
),
foo
{
1
,
2
});
}
}
}
// namespace
CAF_MAIN
()
CAF_MAIN
()
examples/custom_type/custom_types_3.cpp
View file @
71c043cc
// Showcases custom message types that cannot provide
// Showcases custom message types that cannot provide
// friend access to the inspect() function.
// friend access to the inspect() function.
// Manual refs: 20-49, 76-103 (TypeInspection)
#include <utility>
#include <iostream>
#include <iostream>
#include <utility>
#include "caf/all.hpp"
#include "caf/all.hpp"
class
foo
;
CAF_BEGIN_TYPE_ID_BLOCK
(
custom_types_3
,
first_custom_type_id
)
CAF_ADD_TYPE_ID
(
custom_types_3
,
foo
)
CAF_END_TYPE_ID_BLOCK
(
custom_types_3
)
using
std
::
cout
;
using
std
::
cout
;
using
std
::
endl
;
using
std
::
endl
;
using
std
::
make_pair
;
using
std
::
make_pair
;
using
namespace
caf
;
using
namespace
caf
;
namespace
{
// Identical to our second custom type example, but no friend access for
// `inspect`.
// identical to our second custom type example, but
// --(rst-foo-begin)--
// no friend access for `inspect`
class
foo
{
class
foo
{
public:
public:
foo
(
int
a0
=
0
,
int
b0
=
0
)
:
a_
(
a0
),
b_
(
b0
)
{
foo
(
int
a0
=
0
,
int
b0
=
0
)
:
a_
(
a0
),
b_
(
b0
)
{
...
@@ -47,19 +52,22 @@ private:
...
@@ -47,19 +52,22 @@ private:
int
a_
;
int
a_
;
int
b_
;
int
b_
;
};
};
// --(rst-foo-end)--
// A lightweight scope guard implementation.
// A lightweight scope guard implementation.
template
<
class
Fun
>
template
<
class
Fun
>
class
scope_guard
{
class
scope_guard
{
public:
public:
scope_guard
(
Fun
f
)
:
fun_
(
std
::
move
(
f
)),
enabled_
(
true
)
{
}
scope_guard
(
Fun
f
)
:
fun_
(
std
::
move
(
f
)),
enabled_
(
true
)
{
}
scope_guard
(
scope_guard
&&
x
)
:
fun_
(
std
::
move
(
x
.
fun_
)),
enabled_
(
x
.
enabled_
)
{
scope_guard
(
scope_guard
&&
x
)
:
fun_
(
std
::
move
(
x
.
fun_
)),
enabled_
(
x
.
enabled_
)
{
x
.
enabled_
=
false
;
x
.
enabled_
=
false
;
}
}
~
scope_guard
()
{
~
scope_guard
()
{
if
(
enabled_
)
fun_
();
if
(
enabled_
)
fun_
();
}
}
private:
private:
...
@@ -73,17 +81,12 @@ scope_guard<Fun> make_scope_guard(Fun f) {
...
@@ -73,17 +81,12 @@ scope_guard<Fun> make_scope_guard(Fun f) {
return
{
std
::
move
(
f
)};
return
{
std
::
move
(
f
)};
}
}
// --(rst-inspect-begin)--
template
<
class
Inspector
>
template
<
class
Inspector
>
typename
std
::
enable_if
<
Inspector
::
reads_state
,
typename
Inspector
::
result_type
inspect
(
Inspector
&
f
,
foo
&
x
)
{
typename
Inspector
::
result_type
>::
type
if
constexpr
(
Inspector
::
reads_state
)
{
inspect
(
Inspector
&
f
,
foo
&
x
)
{
return
f
(
meta
::
type_name
(
"foo"
),
x
.
a
(),
x
.
b
());
return
f
(
meta
::
type_name
(
"foo"
),
x
.
a
(),
x
.
b
());
}
}
else
{
template
<
class
Inspector
>
typename
std
::
enable_if
<
Inspector
::
writes_state
,
typename
Inspector
::
result_type
>::
type
inspect
(
Inspector
&
f
,
foo
&
x
)
{
int
a
;
int
a
;
int
b
;
int
b
;
// write back to x at scope exit
// write back to x at scope exit
...
@@ -92,20 +95,20 @@ inspect(Inspector& f, foo& x) {
...
@@ -92,20 +95,20 @@ inspect(Inspector& f, foo& x) {
x
.
set_b
(
b
);
x
.
set_b
(
b
);
});
});
return
f
(
meta
::
type_name
(
"foo"
),
a
,
b
);
return
f
(
meta
::
type_name
(
"foo"
),
a
,
b
);
}
}
}
// --(rst-inspect-end)--
behavior
testee
(
event_based_actor
*
self
)
{
behavior
testee
(
event_based_actor
*
self
)
{
return
{
return
{
[
=
](
const
foo
&
x
)
{
[
=
](
const
foo
&
x
)
{
aout
(
self
)
<<
to_string
(
x
)
<<
endl
;
},
aout
(
self
)
<<
to_string
(
x
)
<<
endl
;
}
};
};
}
}
class
config
:
public
actor_system_config
{
class
config
:
public
actor_system_config
{
public:
public:
config
()
{
config
()
{
add_message_type
<
foo
>
(
"foo"
);
init_global_meta_objects
<
custom_types_3_type_ids
>
(
);
}
}
};
};
...
@@ -113,6 +116,4 @@ void caf_main(actor_system& system, const config&) {
...
@@ -113,6 +116,4 @@ void caf_main(actor_system& system, const config&) {
anon_send
(
system
.
spawn
(
testee
),
foo
{
1
,
2
});
anon_send
(
system
.
spawn
(
testee
),
foo
{
1
,
2
});
}
}
}
// namespace
CAF_MAIN
()
CAF_MAIN
()
examples/dynamic_behavior/dining_philosophers.cpp
View file @
71c043cc
...
@@ -13,6 +13,15 @@
...
@@ -13,6 +13,15 @@
#include "caf/all.hpp"
#include "caf/all.hpp"
CAF_BEGIN_TYPE_ID_BLOCK
(
dining_philosophers
,
first_custom_type_id
)
CAF_ADD_ATOM
(
dining_philosophers
,
take_atom
);
CAF_ADD_ATOM
(
dining_philosophers
,
taken_atom
);
CAF_ADD_ATOM
(
dining_philosophers
,
eat_atom
);
CAF_ADD_ATOM
(
dining_philosophers
,
think_atom
);
CAF_END_TYPE_ID_BLOCK
(
dining_philosophers
)
using
std
::
cerr
;
using
std
::
cerr
;
using
std
::
cout
;
using
std
::
cout
;
using
std
::
endl
;
using
std
::
endl
;
...
@@ -23,10 +32,6 @@ using namespace caf;
...
@@ -23,10 +32,6 @@ using namespace caf;
namespace
{
namespace
{
// atoms for chopstick and philosopher interfaces
// atoms for chopstick and philosopher interfaces
CAF_MSG_TYPE_ADD_ATOM
(
take_atom
);
CAF_MSG_TYPE_ADD_ATOM
(
taken_atom
);
CAF_MSG_TYPE_ADD_ATOM
(
eat_atom
);
CAF_MSG_TYPE_ADD_ATOM
(
think_atom
);
// a chopstick
// a chopstick
using
chopstick
=
typed_actor
<
replies_to
<
take_atom
>::
with
<
taken_atom
,
bool
>
,
using
chopstick
=
typed_actor
<
replies_to
<
take_atom
>::
with
<
taken_atom
,
bool
>
,
...
@@ -172,10 +177,7 @@ private:
...
@@ -172,10 +177,7 @@ private:
struct
config
:
actor_system_config
{
struct
config
:
actor_system_config
{
config
()
{
config
()
{
add_message_type
<
take_atom
>
(
"take_atom"
);
init_global_meta_objects
<
dining_philosophers_type_ids
>
();
add_message_type
<
taken_atom
>
(
"taken_atom"
);
add_message_type
<
eat_atom
>
(
"eat_atom"
);
add_message_type
<
think_atom
>
(
"think_atom"
);
}
}
};
};
...
...
examples/message_passing/fan_out_request.cpp
View file @
71c043cc
...
@@ -14,19 +14,25 @@
...
@@ -14,19 +14,25 @@
#include "caf/event_based_actor.hpp"
#include "caf/event_based_actor.hpp"
#include "caf/exec_main.hpp"
#include "caf/exec_main.hpp"
#include "caf/function_view.hpp"
#include "caf/function_view.hpp"
#include "caf/init_global_meta_objects.hpp"
#include "caf/policy/select_all.hpp"
#include "caf/policy/select_all.hpp"
#include "caf/scoped_actor.hpp"
#include "caf/scoped_actor.hpp"
#include "caf/stateful_actor.hpp"
#include "caf/stateful_actor.hpp"
#include "caf/typed_actor.hpp"
#include "caf/typed_actor.hpp"
#include "caf/typed_event_based_actor.hpp"
#include "caf/typed_event_based_actor.hpp"
CAF_BEGIN_TYPE_ID_BLOCK
(
fan_out_request
,
first_custom_type_id
)
CAF_ADD_ATOM
(
fan_out_request
,
row_atom
);
CAF_ADD_ATOM
(
fan_out_request
,
column_atom
);
CAF_ADD_ATOM
(
fan_out_request
,
average_atom
);
CAF_END_TYPE_ID_BLOCK
(
fan_out_request
)
using
std
::
endl
;
using
std
::
endl
;
using
std
::
chrono
::
seconds
;
using
std
::
chrono
::
seconds
;
using
namespace
caf
;
using
namespace
caf
;
CAF_MSG_TYPE_ADD_ATOM
(
row_atom
);
CAF_MSG_TYPE_ADD_ATOM
(
column_atom
);
CAF_MSG_TYPE_ADD_ATOM
(
average_atom
);
/// A simple actor for storing an integer value.
/// A simple actor for storing an integer value.
using
cell
=
typed_actor
<
using
cell
=
typed_actor
<
...
@@ -124,9 +130,7 @@ std::ostream& operator<<(std::ostream& out, const expected<int>& x) {
...
@@ -124,9 +130,7 @@ std::ostream& operator<<(std::ostream& out, const expected<int>& x) {
struct
config
:
actor_system_config
{
struct
config
:
actor_system_config
{
config
()
{
config
()
{
add_message_type
<
row_atom
>
(
"row_atom"
);
init_global_meta_objects
<
fan_out_request_type_ids
>
();
add_message_type
<
column_atom
>
(
"column_atom"
);
add_message_type
<
average_atom
>
(
"average_atom"
);
}
}
};
};
...
...
examples/message_passing/fixed_stack.cpp
View file @
71c043cc
...
@@ -3,21 +3,21 @@
...
@@ -3,21 +3,21 @@
#include <cstdint>
#include <cstdint>
#include <iostream>
#include <iostream>
using
std
::
endl
;
CAF_BEGIN_TYPE_ID_BLOCK
(
fixed_stack
,
first_custom_type_id
)
using
namespace
caf
;
CAF_ADD_ATOM
(
fixed_stack
,
pop_atom
);
CAF_ADD_ATOM
(
fixed_stack
,
push_atom
);
namespace
{
CAF_END_TYPE_ID_BLOCK
(
fixed_stack
)
CAF_MSG_TYPE_ADD_ATOM
(
pop_atom
)
;
using
std
::
endl
;
CAF_MSG_TYPE_ADD_ATOM
(
push_atom
)
;
using
namespace
caf
;
enum
class
fixed_stack_errc
:
uint8_t
{
enum
class
fixed_stack_errc
:
uint8_t
{
push_to_full
=
1
,
push_to_full
=
1
,
pop_from_empty
,
pop_from_empty
,
};
};
}
// namespace
namespace
caf
{
namespace
caf
{
template
<
>
template
<
>
...
@@ -27,8 +27,6 @@ struct error_category<fixed_stack_errc> {
...
@@ -27,8 +27,6 @@ struct error_category<fixed_stack_errc> {
}
// namespace caf
}
// namespace caf
namespace
{
class
fixed_stack
:
public
event_based_actor
{
class
fixed_stack
:
public
event_based_actor
{
public:
public:
fixed_stack
(
actor_config
&
cfg
,
size_t
stack_size
)
fixed_stack
(
actor_config
&
cfg
,
size_t
stack_size
)
...
@@ -75,6 +73,12 @@ private:
...
@@ -75,6 +73,12 @@ 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
);
...
@@ -93,6 +97,4 @@ void caf_main(actor_system& system) {
...
@@ -93,6 +97,4 @@ void caf_main(actor_system& system) {
self
->
send_exit
(
st
,
exit_reason
::
user_shutdown
);
self
->
send_exit
(
st
,
exit_reason
::
user_shutdown
);
}
}
}
// namespace
CAF_MAIN
()
CAF_MAIN
()
examples/remoting/distributed_calculator.cpp
View file @
71c043cc
...
@@ -274,7 +274,8 @@ void client_repl(actor_system& system, const config& cfg) {
...
@@ -274,7 +274,8 @@ void client_repl(actor_system& system, const config& cfg) {
line
=
trim
(
std
::
move
(
line
));
// ignore leading and trailing whitespaces
line
=
trim
(
std
::
move
(
line
));
// ignore leading and trailing whitespaces
std
::
vector
<
string
>
words
;
std
::
vector
<
string
>
words
;
split
(
words
,
line
,
is_any_of
(
" "
),
token_compress_on
);
split
(
words
,
line
,
is_any_of
(
" "
),
token_compress_on
);
if
(
!
message_builder
(
words
.
begin
(),
words
.
end
()).
apply
(
eval
))
auto
msg
=
message_builder
(
words
.
begin
(),
words
.
end
()).
move_to_message
();
if
(
!
eval
(
msg
))
usage
();
usage
();
}
}
}
}
...
...
examples/remoting/group_chat.cpp
View file @
71c043cc
...
@@ -20,46 +20,47 @@
...
@@ -20,46 +20,47 @@
#include "caf/string_algorithms.hpp"
#include "caf/string_algorithms.hpp"
using
namespace
std
;
CAF_BEGIN_TYPE_ID_BLOCK
(
group_chat
,
first_custom_type_id
)
using
namespace
caf
;
CAF_ADD_ATOM
(
group_chat
,
broadcast_atom
);
namespace
{
CAF_END_TYPE_ID_BLOCK
(
group_chat
)
CAF_MSG_TYPE_ADD_ATOM
(
broadcast_atom
)
;
using
namespace
caf
;
struct
line
{
struct
line
{
string
str
;
st
d
::
st
ring
str
;
};
};
istream
&
operator
>>
(
istream
&
is
,
line
&
l
)
{
std
::
istream
&
operator
>>
(
std
::
istream
&
is
,
line
&
l
)
{
getline
(
is
,
l
.
str
);
std
::
getline
(
is
,
l
.
str
);
return
is
;
return
is
;
}
}
behavior
client
(
event_based_actor
*
self
,
const
string
&
name
)
{
behavior
client
(
event_based_actor
*
self
,
const
st
d
::
st
ring
&
name
)
{
return
{
return
{
[
=
](
broadcast_atom
,
const
string
&
message
)
{
[
=
](
broadcast_atom
,
const
st
d
::
st
ring
&
message
)
{
for
(
auto
&
dest
:
self
->
joined_groups
())
{
for
(
auto
&
dest
:
self
->
joined_groups
())
{
self
->
send
(
dest
,
name
+
": "
+
message
);
self
->
send
(
dest
,
name
+
": "
+
message
);
}
}
},
},
[
=
](
join_atom
,
const
group
&
what
)
{
[
=
](
join_atom
,
const
group
&
what
)
{
for
(
const
auto
&
g
:
self
->
joined_groups
())
{
for
(
const
auto
&
g
:
self
->
joined_groups
())
{
cout
<<
"*** leave "
<<
to_string
(
g
)
<<
endl
;
std
::
cout
<<
"*** leave "
<<
to_string
(
g
)
<<
std
::
endl
;
self
->
send
(
g
,
name
+
" has left the chatroom"
);
self
->
send
(
g
,
name
+
" has left the chatroom"
);
self
->
leave
(
g
);
self
->
leave
(
g
);
}
}
cout
<<
"*** join "
<<
to_string
(
what
)
<<
endl
;
std
::
cout
<<
"*** join "
<<
to_string
(
what
)
<<
std
::
endl
;
self
->
join
(
what
);
self
->
join
(
what
);
self
->
send
(
what
,
name
+
" has entered the chatroom"
);
self
->
send
(
what
,
name
+
" has entered the chatroom"
);
},
},
[
=
](
const
string
&
txt
)
{
[
=
](
const
st
d
::
st
ring
&
txt
)
{
// don't print own messages
// don't print own messages
if
(
self
->
current_sender
()
!=
self
)
if
(
self
->
current_sender
()
!=
self
)
cout
<<
txt
<<
endl
;
std
::
cout
<<
txt
<<
std
::
endl
;
},
},
[
=
](
const
group_down_msg
&
g
)
{
[
=
](
const
group_down_msg
&
g
)
{
cout
<<
"*** chatroom offline: "
<<
to_string
(
g
.
source
)
<<
endl
;
std
::
cout
<<
"*** chatroom offline: "
<<
to_string
(
g
.
source
)
<<
std
::
endl
;
},
},
};
};
}
}
...
@@ -72,6 +73,7 @@ public:
...
@@ -72,6 +73,7 @@ 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"
)
...
@@ -84,48 +86,47 @@ void run_server(actor_system& system, const config& cfg) {
...
@@ -84,48 +86,47 @@ void run_server(actor_system& system, const config& cfg) {
auto
res
=
system
.
middleman
().
publish_local_groups
(
cfg
.
port
);
auto
res
=
system
.
middleman
().
publish_local_groups
(
cfg
.
port
);
if
(
!
res
)
{
if
(
!
res
)
{
std
::
cerr
<<
"*** publishing local groups failed: "
std
::
cerr
<<
"*** publishing local groups failed: "
<<
system
.
render
(
res
.
error
())
<<
endl
;
<<
system
.
render
(
res
.
error
())
<<
std
::
endl
;
return
;
return
;
}
}
cout
<<
"*** listening at port "
<<
*
res
<<
endl
std
::
cout
<<
"*** listening at port "
<<
*
res
<<
std
::
endl
<<
"*** press [enter] to quit"
<<
endl
;
<<
"*** press [enter] to quit"
<<
std
::
endl
;
string
dummy
;
st
d
::
st
ring
dummy
;
std
::
getline
(
std
::
cin
,
dummy
);
std
::
getline
(
std
::
cin
,
dummy
);
cout
<<
"... cya"
<<
endl
;
std
::
cout
<<
"... cya"
<<
std
::
endl
;
}
}
void
run_client
(
actor_system
&
system
,
const
config
&
cfg
)
{
void
run_client
(
actor_system
&
system
,
const
config
&
cfg
)
{
auto
name
=
cfg
.
name
;
auto
name
=
cfg
.
name
;
while
(
name
.
empty
())
{
while
(
name
.
empty
())
{
cout
<<
"please enter your name: "
<<
flush
;
std
::
cout
<<
"please enter your name: "
<<
std
::
flush
;
if
(
!
getline
(
cin
,
name
))
{
if
(
!
std
::
getline
(
std
::
cin
,
name
))
{
cerr
<<
"*** no name given... terminating"
<<
endl
;
std
::
cerr
<<
"*** no name given... terminating"
<<
std
::
endl
;
return
;
return
;
}
}
}
}
cout
<<
"*** starting client, type '/help' for a list of commands"
<<
endl
;
std
::
cout
<<
"*** starting client, type '/help' for a list of commands
\n
"
;
auto
client_actor
=
system
.
spawn
(
client
,
name
);
auto
client_actor
=
system
.
spawn
(
client
,
name
);
for
(
auto
&
uri
:
cfg
.
group_uris
)
{
for
(
auto
&
uri
:
cfg
.
group_uris
)
{
auto
tmp
=
system
.
groups
().
get
(
uri
);
auto
tmp
=
system
.
groups
().
get
(
uri
);
if
(
tmp
)
if
(
tmp
)
anon_send
(
client_actor
,
join_atom_v
,
std
::
move
(
*
tmp
));
anon_send
(
client_actor
,
join_atom_v
,
std
::
move
(
*
tmp
));
else
else
cerr
<<
R"(*** failed to parse ")"
<<
uri
<<
R"(" as group URI: )"
std
::
cerr
<<
R"(*** failed to parse ")"
<<
uri
<<
R"(" as group URI: )"
<<
system
.
render
(
tmp
.
error
())
<<
endl
;
<<
system
.
render
(
tmp
.
error
())
<<
std
::
endl
;
}
}
istream_iterator
<
line
>
eof
;
std
::
istream_iterator
<
line
>
eof
;
vector
<
string
>
words
;
std
::
vector
<
std
::
string
>
words
;
for
(
istream_iterator
<
line
>
i
(
cin
)
;
i
!=
eof
;
++
i
)
{
for
(
std
::
istream_iterator
<
line
>
i
{
std
::
cin
}
;
i
!=
eof
;
++
i
)
{
auto
send_input
=
[
&
]
{
auto
send_input
=
[
&
]
{
if
(
!
i
->
str
.
empty
())
if
(
!
i
->
str
.
empty
())
anon_send
(
client_actor
,
broadcast_atom_v
,
i
->
str
);
anon_send
(
client_actor
,
broadcast_atom_v
,
i
->
str
);
};
};
words
.
clear
();
words
.
clear
();
split
(
words
,
i
->
str
,
is_any_of
(
" "
));
split
(
words
,
i
->
str
,
is_any_of
(
" "
));
auto
res
message_handler
f
{
=
message_builder
(
words
.
begin
(),
words
.
end
())
[
&
](
const
std
::
string
&
cmd
,
const
std
::
string
&
mod
,
.
apply
(
const
std
::
string
&
id
)
{
{[
&
](
const
string
&
cmd
,
const
string
&
mod
,
const
string
&
id
)
{
if
(
cmd
==
"/join"
)
{
if
(
cmd
==
"/join"
)
{
auto
grp
=
system
.
groups
().
get
(
mod
,
id
);
auto
grp
=
system
.
groups
().
get
(
mod
,
id
);
if
(
grp
)
if
(
grp
)
...
@@ -134,19 +135,21 @@ void run_client(actor_system& system, const config& cfg) {
...
@@ -134,19 +135,21 @@ void run_client(actor_system& system, const config& cfg) {
send_input
();
send_input
();
}
}
},
},
[
&
](
const
string
&
cmd
)
{
[
&
](
const
std
::
string
&
cmd
)
{
if
(
cmd
==
"/quit"
)
{
if
(
cmd
==
"/quit"
)
{
cin
.
setstate
(
ios_base
::
eofbit
);
std
::
cin
.
setstate
(
std
::
ios_base
::
eofbit
);
}
else
if
(
cmd
[
0
]
==
'/'
)
{
}
else
if
(
cmd
[
0
]
==
'/'
)
{
cout
<<
"*** available commands:
\n
"
std
::
cout
<<
"*** available commands:
\n
"
" /join <module> <group> join a new chat channel
\n
"
" /join <module> <group> join a new chat channel
\n
"
" /quit quit the program
\n
"
" /quit quit the program
\n
"
" /help print this text
\n
"
" /help print this text
\n
"
;
<<
flush
;
}
else
{
}
else
{
send_input
();
send_input
();
}
}
}});
},
};
auto
msg
=
message_builder
(
words
.
begin
(),
words
.
end
()).
move_to_message
();
auto
res
=
f
(
msg
);
if
(
!
res
)
if
(
!
res
)
send_input
();
send_input
();
}
}
...
@@ -159,6 +162,4 @@ void caf_main(actor_system& system, const config& cfg) {
...
@@ -159,6 +162,4 @@ void caf_main(actor_system& system, const config& cfg) {
f
(
system
,
cfg
);
f
(
system
,
cfg
);
}
}
}
// namespace
CAF_MAIN
(
io
::
middleman
)
CAF_MAIN
(
io
::
middleman
)
examples/remoting/remote_spawn.cpp
View file @
71c043cc
...
@@ -7,9 +7,6 @@
...
@@ -7,9 +7,6 @@
// Run client at the same host:
// Run client at the same host:
// - remote_spawn -H localhost -p 4242
// - remote_spawn -H localhost -p 4242
// Manual refs: 33-34, 98-109 (ConfiguringActorApplications)
// 123-137 (RemoteSpawn)
#include <array>
#include <array>
#include <cassert>
#include <cassert>
#include <functional>
#include <functional>
...
@@ -21,6 +18,18 @@
...
@@ -21,6 +18,18 @@
#include "caf/all.hpp"
#include "caf/all.hpp"
#include "caf/io/all.hpp"
#include "caf/io/all.hpp"
// --(rst-calculator-begin)--
using
calculator
=
caf
::
typed_actor
<
caf
::
replies_to
<
caf
::
add_atom
,
int
,
int
>::
with
<
int
>
,
caf
::
replies_to
<
caf
::
sub_atom
,
int
,
int
>::
with
<
int
>>
;
// --(rst-calculator-end)--
CAF_BEGIN_TYPE_ID_BLOCK
(
remote_spawn
,
first_custom_type_id
)
CAF_ADD_TYPE_ID
(
remote_spawn
,
calculator
)
CAF_END_TYPE_ID_BLOCK
(
remote_spawn
)
using
std
::
cerr
;
using
std
::
cerr
;
using
std
::
cout
;
using
std
::
cout
;
using
std
::
endl
;
using
std
::
endl
;
...
@@ -28,11 +37,6 @@ using std::string;
...
@@ -28,11 +37,6 @@ using std::string;
using
namespace
caf
;
using
namespace
caf
;
namespace
{
using
calculator
=
typed_actor
<
replies_to
<
add_atom
,
int
,
int
>::
with
<
int
>
,
replies_to
<
sub_atom
,
int
,
int
>::
with
<
int
>>
;
calculator
::
behavior_type
calculator_fun
(
calculator
::
pointer
self
)
{
calculator
::
behavior_type
calculator_fun
(
calculator
::
pointer
self
)
{
return
{
return
{
[
=
](
add_atom
,
int
a
,
int
b
)
->
int
{
[
=
](
add_atom
,
int
a
,
int
b
)
->
int
{
...
@@ -98,6 +102,7 @@ void client_repl(function_view<calculator> f) {
...
@@ -98,6 +102,7 @@ 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)"
)
...
@@ -119,6 +124,7 @@ void server(actor_system& system, const config& cfg) {
...
@@ -119,6 +124,7 @@ void server(actor_system& system, const config& cfg) {
getchar
();
getchar
();
}
}
// --(rst-client-begin)--
void
client
(
actor_system
&
system
,
const
config
&
cfg
)
{
void
client
(
actor_system
&
system
,
const
config
&
cfg
)
{
auto
node
=
system
.
middleman
().
connect
(
cfg
.
host
,
cfg
.
port
);
auto
node
=
system
.
middleman
().
connect
(
cfg
.
host
,
cfg
.
port
);
if
(
!
node
)
{
if
(
!
node
)
{
...
@@ -140,12 +146,11 @@ void client(actor_system& system, const config& cfg) {
...
@@ -140,12 +146,11 @@ void client(actor_system& system, const config& cfg) {
// be a good citizen and terminate remotely spawned actor before exiting
// be a good citizen and terminate remotely spawned actor before exiting
anon_send_exit
(
*
worker
,
exit_reason
::
kill
);
anon_send_exit
(
*
worker
,
exit_reason
::
kill
);
}
}
// --(rst-client-end)--
void
caf_main
(
actor_system
&
system
,
const
config
&
cfg
)
{
void
caf_main
(
actor_system
&
system
,
const
config
&
cfg
)
{
auto
f
=
cfg
.
server_mode
?
server
:
client
;
auto
f
=
cfg
.
server_mode
?
server
:
client
;
f
(
system
,
cfg
);
f
(
system
,
cfg
);
}
}
}
// namespace
CAF_MAIN
(
io
::
middleman
)
CAF_MAIN
(
io
::
middleman
)
examples/streaming/integer_stream.cpp
View file @
71c043cc
...
@@ -2,22 +2,28 @@
...
@@ -2,22 +2,28 @@
* Basic, non-interactive streaming example for processing integers. *
* Basic, non-interactive streaming example for processing integers. *
******************************************************************************/
******************************************************************************/
// Manual refs: lines 17-48, 50-83, 85-114, 128-132 (Streaming)
#include <iostream>
#include <iostream>
#include <vector>
#include <vector>
#include "caf/all.hpp"
#include "caf/all.hpp"
CAF_BEGIN_TYPE_ID_BLOCK
(
integer_stream
,
first_custom_type_id
)
CAF_ADD_TYPE_ID
(
integer_stream
,
caf
::
stream
<
int32_t
>
)
CAF_ADD_TYPE_ID
(
integer_stream
,
std
::
vector
<
int32_t
>
)
CAF_END_TYPE_ID_BLOCK
(
integer_stream
)
using
std
::
endl
;
using
std
::
endl
;
using
namespace
caf
;
using
namespace
caf
;
namespace
{
namespace
{
// --(rst-source-begin)--
// Simple source for generating a stream of integers from [0, n).
// Simple source for generating a stream of integers from [0, n).
behavior
int_source
(
event_based_actor
*
self
)
{
behavior
int_source
(
event_based_actor
*
self
)
{
return
{
return
{
[
=
](
open_atom
,
int
n
)
{
[
=
](
open_atom
,
int
32_t
n
)
{
// Produce at least one value.
// Produce at least one value.
if
(
n
<=
0
)
if
(
n
<=
0
)
n
=
1
;
n
=
1
;
...
@@ -28,7 +34,7 @@ behavior int_source(event_based_actor* self) {
...
@@ -28,7 +34,7 @@ behavior int_source(event_based_actor* self) {
self
,
self
,
// Initializer. The type of the first argument (state) is freely
// Initializer. The type of the first argument (state) is freely
// chosen. If no state is required, `caf::unit_t` can be used here.
// chosen. If no state is required, `caf::unit_t` can be used here.
[](
int
&
x
)
{
x
=
0
;
},
[](
int
32_t
&
x
)
{
x
=
0
;
},
// Generator. This function is called by CAF to produce new stream
// Generator. This function is called by CAF to produce new stream
// elements for downstream actors. The `x` argument is our state again
// elements for downstream actors. The `x` argument is our state again
// (with our freely chosen type). The second argument `out` points to
// (with our freely chosen type). The second argument `out` points to
...
@@ -36,21 +42,23 @@ behavior int_source(event_based_actor* self) {
...
@@ -36,21 +42,23 @@ behavior int_source(event_based_actor* self) {
// elements downstream actors receive in this stream. Finally, `num` is
// elements downstream actors receive in this stream. Finally, `num` is
// a hint from CAF how many elements we should ideally insert into
// a hint from CAF how many elements we should ideally insert into
// `out`. We can always insert fewer or more items.
// `out`. We can always insert fewer or more items.
[
n
](
int
&
x
,
downstream
<
in
t
>&
out
,
size_t
num
)
{
[
n
](
int
32_t
&
x
,
downstream
<
int32_
t
>&
out
,
size_t
num
)
{
auto
max_x
=
std
::
min
(
x
+
static_cast
<
int
>
(
num
),
n
);
auto
max_x
=
std
::
min
(
x
+
static_cast
<
int
>
(
num
),
n
);
for
(;
x
<
max_x
;
++
x
)
for
(;
x
<
max_x
;
++
x
)
out
.
push
(
x
);
out
.
push
(
x
);
},
},
// Predicate. This function tells CAF when we reached the end.
// Predicate. This function tells CAF when we reached the end.
[
n
](
const
int
&
x
)
{
return
x
==
n
;
});
[
n
](
const
int
32_t
&
x
)
{
return
x
==
n
;
});
},
},
};
};
}
}
// --(rst-source-end)--
// --(rst-stage-begin)--
// Simple stage that only selects even numbers.
// Simple stage that only selects even numbers.
behavior
int_selector
(
event_based_actor
*
self
)
{
behavior
int_selector
(
event_based_actor
*
self
)
{
return
{
return
{
[
=
](
stream
<
int
>
in
)
{
[
=
](
stream
<
int
32_t
>
in
)
{
// Create a stream manager for implementing a stream stage. Similar to
// Create a stream manager for implementing a stream stage. Similar to
// `make_source`, we need three functions: initialzer, processor, and
// `make_source`, we need three functions: initialzer, processor, and
// finalizer.
// finalizer.
...
@@ -64,7 +72,7 @@ behavior int_selector(event_based_actor* self) {
...
@@ -64,7 +72,7 @@ behavior int_selector(event_based_actor* self) {
},
},
// Processor. This function takes individual input elements as `val`
// Processor. This function takes individual input elements as `val`
// and forwards even integers to `out`.
// and forwards even integers to `out`.
[](
unit_t
&
,
downstream
<
int
>&
out
,
in
t
val
)
{
[](
unit_t
&
,
downstream
<
int
32_t
>&
out
,
int32_
t
val
)
{
if
(
val
%
2
==
0
)
if
(
val
%
2
==
0
)
out
.
push
(
val
);
out
.
push
(
val
);
},
},
...
@@ -81,10 +89,12 @@ behavior int_selector(event_based_actor* self) {
...
@@ -81,10 +89,12 @@ behavior int_selector(event_based_actor* self) {
},
},
};
};
}
}
// --(rst-stage-end)--
// --(rst-sink-begin)--
behavior
int_sink
(
event_based_actor
*
self
)
{
behavior
int_sink
(
event_based_actor
*
self
)
{
return
{
return
{
[
=
](
stream
<
int
>
in
)
{
[
=
](
stream
<
int
32_t
>
in
)
{
// Create a stream manager for implementing a stream sink. Once more, we
// Create a stream manager for implementing a stream sink. Once more, we
// have to provide three functions: Initializer, Consumer, Finalizer.
// have to provide three functions: Initializer, Consumer, Finalizer.
return
attach_stream_sink
(
return
attach_stream_sink
(
...
@@ -99,9 +109,9 @@ behavior int_sink(event_based_actor* self) {
...
@@ -99,9 +109,9 @@ behavior int_sink(event_based_actor* self) {
},
},
// Consumer. Takes individual input elements as `val` and stores them
// Consumer. Takes individual input elements as `val` and stores them
// in our history.
// in our history.
[](
std
::
vector
<
int
>&
xs
,
in
t
val
)
{
xs
.
emplace_back
(
val
);
},
[](
std
::
vector
<
int
32_t
>&
xs
,
int32_
t
val
)
{
xs
.
emplace_back
(
val
);
},
// Finalizer. Allows us to run cleanup code once the stream terminates.
// Finalizer. Allows us to run cleanup code once the stream terminates.
[
=
](
std
::
vector
<
int
>&
xs
,
const
error
&
err
)
{
[
=
](
std
::
vector
<
int
32_t
>&
xs
,
const
error
&
err
)
{
if
(
err
)
{
if
(
err
)
{
aout
(
self
)
<<
"int_sink aborted with error: "
<<
err
<<
std
::
endl
;
aout
(
self
)
<<
"int_sink aborted with error: "
<<
err
<<
std
::
endl
;
}
else
{
}
else
{
...
@@ -112,18 +122,21 @@ behavior int_sink(event_based_actor* self) {
...
@@ -112,18 +122,21 @@ behavior int_sink(event_based_actor* self) {
},
},
};
};
}
}
// --(rst-sink-end)--
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"
);
}
}
bool
with_stage
=
false
;
bool
with_stage
=
false
;
int
n
=
100
;
int
32_t
n
=
100
;
};
};
// --(rst-main-begin)--
void
caf_main
(
actor_system
&
sys
,
const
config
&
cfg
)
{
void
caf_main
(
actor_system
&
sys
,
const
config
&
cfg
)
{
auto
src
=
sys
.
spawn
(
int_source
);
auto
src
=
sys
.
spawn
(
int_source
);
auto
snk
=
sys
.
spawn
(
int_sink
);
auto
snk
=
sys
.
spawn
(
int_sink
);
...
@@ -131,6 +144,7 @@ void caf_main(actor_system& sys, const config& cfg) {
...
@@ -131,6 +144,7 @@ void caf_main(actor_system& sys, const config& cfg) {
:
snk
*
src
;
:
snk
*
src
;
anon_send
(
pipeline
,
open_atom_v
,
cfg
.
n
);
anon_send
(
pipeline
,
open_atom_v
,
cfg
.
n
);
}
}
// --(rst-main-end)--
}
// namespace
}
// namespace
...
...
libcaf_core/CMakeLists.txt
View file @
71c043cc
...
@@ -69,6 +69,7 @@ set(CAF_CORE_SOURCES
...
@@ -69,6 +69,7 @@ set(CAF_CORE_SOURCES
src/detail/get_root_uuid.cpp
src/detail/get_root_uuid.cpp
src/detail/ini_consumer.cpp
src/detail/ini_consumer.cpp
src/detail/invoke_result_visitor.cpp
src/detail/invoke_result_visitor.cpp
src/detail/message_builder_element.cpp
src/detail/message_data.cpp
src/detail/message_data.cpp
src/detail/meta_object.cpp
src/detail/meta_object.cpp
src/detail/parse.cpp
src/detail/parse.cpp
...
...
libcaf_core/caf/binary_deserializer.hpp
View file @
71c043cc
...
@@ -104,7 +104,7 @@ public:
...
@@ -104,7 +104,7 @@ public:
// -- overridden member functions --------------------------------------------
// -- overridden member functions --------------------------------------------
result_type
begin_object
(
uint16_t
&
typenr
,
std
::
string
&
nam
e
);
result_type
begin_object
(
type_id_t
&
typ
e
);
result_type
end_object
()
noexcept
;
result_type
end_object
()
noexcept
;
...
...
libcaf_core/caf/binary_serializer.hpp
View file @
71c043cc
...
@@ -95,7 +95,7 @@ public:
...
@@ -95,7 +95,7 @@ public:
// -- interface functions ----------------------------------------------------
// -- interface functions ----------------------------------------------------
error_code
<
sec
>
begin_object
(
uint16_t
nr
,
string_view
nam
e
);
error_code
<
sec
>
begin_object
(
type_id_t
typ
e
);
error_code
<
sec
>
end_object
();
error_code
<
sec
>
end_object
();
...
...
libcaf_core/caf/deserializer.hpp
View file @
71c043cc
...
@@ -57,8 +57,7 @@ public:
...
@@ -57,8 +57,7 @@ public:
// -- interface functions ----------------------------------------------------
// -- interface functions ----------------------------------------------------
/// Begins processing of an object.
/// Begins processing of an object.
virtual
result_type
begin_object
(
uint16_t
&
typenr
,
std
::
string
&
type_name
)
virtual
result_type
begin_object
(
type_id_t
&
type
)
=
0
;
=
0
;
/// Ends processing of an object.
/// Ends processing of an object.
virtual
result_type
end_object
()
=
0
;
virtual
result_type
end_object
()
=
0
;
...
...
libcaf_core/caf/detail/append_hex.hpp
View file @
71c043cc
...
@@ -21,25 +21,25 @@
...
@@ -21,25 +21,25 @@
#include <string>
#include <string>
#include <type_traits>
#include <type_traits>
#include "caf/byte.hpp"
#include "caf/detail/core_export.hpp"
#include "caf/detail/core_export.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/detail/type_traits.hpp"
namespace
caf
::
detail
{
namespace
caf
::
detail
{
CAF_CORE_EXPORT
void
CAF_CORE_EXPORT
void
append_hex
(
std
::
string
&
result
,
const
uint8_t
*
xs
,
size_t
n
);
append_hex
(
std
::
string
&
result
,
const
byte
*
xs
,
size_t
n
);
template
<
class
T
>
template
<
class
T
>
enable_if_t
<
has_data_member
<
T
>::
value
>
enable_if_t
<
has_data_member
<
T
>::
value
>
append_hex
(
std
::
string
&
result
,
const
T
&
x
)
{
append_hex
(
std
::
string
&
result
,
const
T
&
x
)
{
return
append_hex
(
result
,
reinterpret_cast
<
const
uint8_t
*>
(
x
.
data
()),
return
append_hex
(
result
,
reinterpret_cast
<
const
byte
*>
(
x
.
data
()),
x
.
size
());
x
.
size
());
}
}
template
<
class
T
>
template
<
class
T
>
enable_if_t
<
std
::
is_integral
<
T
>::
value
>
enable_if_t
<
std
::
is_integral
<
T
>::
value
>
append_hex
(
std
::
string
&
result
,
const
T
&
x
)
{
append_hex
(
std
::
string
&
result
,
const
T
&
x
)
{
return
append_hex
(
result
,
reinterpret_cast
<
const
uint8_t
*>
(
&
x
),
sizeof
(
T
));
return
append_hex
(
result
,
reinterpret_cast
<
const
byte
*>
(
&
x
),
sizeof
(
T
));
}
}
}
// namespace caf::detail
}
// namespace caf::detail
libcaf_core/caf/detail/make_meta_object.hpp
View file @
71c043cc
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#include "caf/deserializer.hpp"
#include "caf/deserializer.hpp"
#include "caf/detail/meta_object.hpp"
#include "caf/detail/meta_object.hpp"
#include "caf/detail/padded_size.hpp"
#include "caf/detail/padded_size.hpp"
#include "caf/detail/stringification_inspector.hpp"
#include "caf/error.hpp"
#include "caf/error.hpp"
#include "caf/serializer.hpp"
#include "caf/serializer.hpp"
...
@@ -54,6 +55,10 @@ meta_object make_meta_object(const char* type_name) {
...
@@ -54,6 +55,10 @@ meta_object make_meta_object(const char* type_name) {
[](
caf
::
deserializer
&
source
,
void
*
ptr
)
{
[](
caf
::
deserializer
&
source
,
void
*
ptr
)
{
return
source
(
*
reinterpret_cast
<
T
*>
(
ptr
));
return
source
(
*
reinterpret_cast
<
T
*>
(
ptr
));
},
},
[](
std
::
string
&
buf
,
const
void
*
ptr
)
{
stringification_inspector
f
{
buf
};
f
(
*
reinterpret_cast
<
const
T
*>
(
ptr
));
},
};
};
}
}
...
...
libcaf_core/caf/detail/message_builder_element.hpp
View file @
71c043cc
...
@@ -31,7 +31,7 @@ namespace caf::detail {
...
@@ -31,7 +31,7 @@ namespace caf::detail {
/// later.
/// later.
class
CAF_CORE_EXPORT
message_builder_element
{
class
CAF_CORE_EXPORT
message_builder_element
{
public:
public:
virtual
~
message_builder_element
()
noexcept
;
virtual
~
message_builder_element
();
/// Uses placement new to create a copy of the wrapped value at given memory
/// Uses placement new to create a copy of the wrapped value at given memory
/// region.
/// region.
...
...
libcaf_core/caf/detail/message_data.hpp
View file @
71c043cc
...
@@ -147,7 +147,7 @@ void message_data_init(byte* storage, T&& x, Ts&&... xs) {
...
@@ -147,7 +147,7 @@ void message_data_init(byte* storage, T&& x, Ts&&... xs) {
// TODO: exception safety: if any constructor throws, we need to unwind the
// TODO: exception safety: if any constructor throws, we need to unwind the
// stack here and call destructors.
// stack here and call destructors.
using
type
=
strip_and_convert_t
<
T
>
;
using
type
=
strip_and_convert_t
<
T
>
;
new
(
storage
)
strip_and_convert_t
<
T
>
(
std
::
forward
<
T
>
(
x
));
new
(
storage
)
type
(
std
::
forward
<
T
>
(
x
));
message_data_init
(
storage
+
padded_size_v
<
type
>
,
std
::
forward
<
Ts
>
(
xs
)...);
message_data_init
(
storage
+
padded_size_v
<
type
>
,
std
::
forward
<
Ts
>
(
xs
)...);
}
}
...
...
libcaf_core/caf/detail/meta_object.hpp
View file @
71c043cc
...
@@ -58,6 +58,9 @@ struct meta_object {
...
@@ -58,6 +58,9 @@ struct meta_object {
/// Applies an object to a generic deserializer.
/// Applies an object to a generic deserializer.
caf
::
error
(
*
load
)(
caf
::
deserializer
&
,
void
*
);
caf
::
error
(
*
load
)(
caf
::
deserializer
&
,
void
*
);
/// Appends a string representation of an object to a buffer.
void
(
*
stringify
)(
std
::
string
&
,
const
void
*
);
};
};
/// Convenience function for calling `meta.save(sink, obj)`.
/// Convenience function for calling `meta.save(sink, obj)`.
...
@@ -81,7 +84,7 @@ load(const meta_object& meta, caf::binary_deserializer& source, void* obj);
...
@@ -81,7 +84,7 @@ load(const meta_object& meta, caf::binary_deserializer& source, void* obj);
CAF_CORE_EXPORT
span
<
const
meta_object
>
global_meta_objects
();
CAF_CORE_EXPORT
span
<
const
meta_object
>
global_meta_objects
();
/// Returns the global meta object for given type ID.
/// Returns the global meta object for given type ID.
CAF_CORE_EXPORT
meta_object
&
global_meta_object
(
type_id_t
id
);
CAF_CORE_EXPORT
const
meta_object
*
global_meta_object
(
type_id_t
id
);
/// Clears the array for storing global meta objects.
/// Clears the array for storing global meta objects.
/// @warning intended for unit testing only!
/// @warning intended for unit testing only!
...
...
libcaf_core/caf/detail/serialized_size.hpp
View file @
71c043cc
...
@@ -33,7 +33,7 @@ public:
...
@@ -33,7 +33,7 @@ public:
return
result_
;
return
result_
;
}
}
result_type
begin_object
(
uint16_t
typenr
,
string_view
type_name
)
override
;
result_type
begin_object
(
type_id_t
)
override
;
result_type
end_object
()
override
;
result_type
end_object
()
override
;
...
...
libcaf_core/caf/detail/stringification_inspector.hpp
View file @
71c043cc
...
@@ -60,7 +60,7 @@ public:
...
@@ -60,7 +60,7 @@ public:
// -- serializer interface ---------------------------------------------------
// -- serializer interface ---------------------------------------------------
void
begin_object
(
uint16_t
,
string_view
)
{
void
begin_object
(
type_id_t
)
{
// nop
// nop
}
}
...
...
libcaf_core/caf/detail/type_id_list_builder.hpp
View file @
71c043cc
...
@@ -20,12 +20,13 @@
...
@@ -20,12 +20,13 @@
#include <cstdlib>
#include <cstdlib>
#include "caf/detail/core_export.hpp"
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
#include "caf/type_id.hpp"
#include "caf/type_id.hpp"
namespace
caf
::
detail
{
namespace
caf
::
detail
{
class
type_id_list_builder
{
class
CAF_CORE_EXPORT
type_id_list_builder
{
public:
public:
static
constexpr
size_t
block_size
=
8
;
static
constexpr
size_t
block_size
=
8
;
...
...
libcaf_core/caf/intrusive_ptr.hpp
View file @
71c043cc
...
@@ -268,7 +268,7 @@ template <class T>
...
@@ -268,7 +268,7 @@ template <class T>
std
::
string
to_string
(
const
intrusive_ptr
<
T
>&
x
)
{
std
::
string
to_string
(
const
intrusive_ptr
<
T
>&
x
)
{
std
::
string
result
;
std
::
string
result
;
auto
v
=
reinterpret_cast
<
uintptr_t
>
(
x
.
get
());
auto
v
=
reinterpret_cast
<
uintptr_t
>
(
x
.
get
());
detail
::
append_hex
(
result
,
reinterpret_cast
<
uint8_t
*>
(
&
v
),
sizeof
(
v
));
detail
::
append_hex
(
result
,
reinterpret_cast
<
byte
*>
(
&
v
),
sizeof
(
v
));
return
result
;
return
result
;
}
}
...
...
libcaf_core/caf/message.hpp
View file @
71c043cc
...
@@ -182,14 +182,15 @@ template <class... Ts>
...
@@ -182,14 +182,15 @@ template <class... Ts>
message
make_message
(
Ts
&&
...
xs
)
{
message
make_message
(
Ts
&&
...
xs
)
{
using
namespace
detail
;
using
namespace
detail
;
static_assert
((
!
std
::
is_pointer
<
strip_and_convert_t
<
Ts
>>::
value
&&
...));
static_assert
((
!
std
::
is_pointer
<
strip_and_convert_t
<
Ts
>>::
value
&&
...));
static
constexpr
size_t
data_size
=
sizeof
(
message_data
)
static_assert
((
is_complete
<
type_id
<
strip_and_convert_t
<
Ts
>>>
&&
...));
+
(
padded_size_v
<
std
::
decay_t
<
Ts
>>
+
...);
static
constexpr
size_t
data_size
=
sizeof
(
message_data
)
+
(
padded_size_v
<
strip_and_convert_t
<
Ts
>>
+
...);
auto
types
=
make_type_id_list
<
strip_and_convert_t
<
Ts
>
...
>
();
auto
types
=
make_type_id_list
<
strip_and_convert_t
<
Ts
>
...
>
();
auto
vptr
=
malloc
(
data_size
);
auto
vptr
=
malloc
(
data_size
);
if
(
vptr
==
nullptr
)
if
(
vptr
==
nullptr
)
throw
std
::
bad_alloc
();
throw
std
::
bad_alloc
();
auto
raw_ptr
=
new
(
vptr
)
message_data
(
types
);
auto
raw_ptr
=
new
(
vptr
)
message_data
(
types
);
intrusive_cow_ptr
<
message_data
>
ptr
{};
intrusive_cow_ptr
<
message_data
>
ptr
{
raw_ptr
,
false
};
message_data_init
(
raw_ptr
->
storage
(),
std
::
forward
<
Ts
>
(
xs
)...);
message_data_init
(
raw_ptr
->
storage
(),
std
::
forward
<
Ts
>
(
xs
)...);
return
message
{
std
::
move
(
ptr
)};
return
message
{
std
::
move
(
ptr
)};
}
}
...
...
libcaf_core/caf/message_builder.hpp
View file @
71c043cc
...
@@ -58,8 +58,9 @@ public:
...
@@ -58,8 +58,9 @@ public:
/// Adds `x` to the elements of the buffer.
/// Adds `x` to the elements of the buffer.
template
<
class
T
>
template
<
class
T
>
message_builder
&
append
(
T
&&
x
)
{
message_builder
&
append
(
T
&&
x
)
{
using
value_type
=
detail
::
strip_and_convert
<
T
>
;
using
namespace
detail
;
static_assert
(
detail
::
sendable
<
value_type
>
);
using
value_type
=
strip_and_convert_t
<
T
>
;
static_assert
(
sendable
<
value_type
>
);
types_
.
push_back
(
type_id_v
<
value_type
>
);
types_
.
push_back
(
type_id_v
<
value_type
>
);
elements_
.
emplace_back
(
make_message_builder_element
(
std
::
forward
<
T
>
(
x
)));
elements_
.
emplace_back
(
make_message_builder_element
(
std
::
forward
<
T
>
(
x
)));
return
*
this
;
return
*
this
;
...
...
libcaf_core/caf/serializer.hpp
View file @
71c043cc
...
@@ -62,7 +62,7 @@ public:
...
@@ -62,7 +62,7 @@ public:
/// Begins processing of an object. Saves the type information
/// Begins processing of an object. Saves the type information
/// to the underlying storage.
/// to the underlying storage.
virtual
result_type
begin_object
(
uint16_t
typenr
,
string_view
type_nam
e
)
=
0
;
virtual
result_type
begin_object
(
type_id_t
typ
e
)
=
0
;
/// Ends processing of an object.
/// Ends processing of an object.
virtual
result_type
end_object
()
=
0
;
virtual
result_type
end_object
()
=
0
;
...
...
libcaf_core/caf/type_id.hpp
View file @
71c043cc
...
@@ -24,6 +24,7 @@
...
@@ -24,6 +24,7 @@
#include <utility>
#include <utility>
#include "caf/detail/core_export.hpp"
#include "caf/detail/core_export.hpp"
#include "caf/detail/pp.hpp"
#include "caf/detail/squashed_int.hpp"
#include "caf/detail/squashed_int.hpp"
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
#include "caf/meta/type_name.hpp"
#include "caf/meta/type_name.hpp"
...
@@ -120,8 +121,25 @@ constexpr type_id_t first_custom_type_id = 200;
...
@@ -120,8 +121,25 @@ constexpr type_id_t first_custom_type_id = 200;
: type_name<fully_qualified_name> {}; \
: type_name<fully_qualified_name> {}; \
}
}
/// Creates a new tag type (atom) in the global namespace and assigns the next
/// free type ID to it.
#define CAF_ADD_ATOM_2(project_name, atom_name) \
struct atom_name {}; \
static constexpr atom_name atom_name##_v = atom_name{}; \
[[maybe_unused]] constexpr bool operator==(atom_name, atom_name) { \
return true; \
} \
[[maybe_unused]] constexpr bool operator!=(atom_name, atom_name) { \
return false; \
} \
template <class Inspector> \
auto inspect(Inspector& f, atom_name&) { \
return f(caf::meta::type_name(#atom_name)); \
} \
CAF_ADD_TYPE_ID(project_name, atom_name)
/// Creates a new tag type (atom) and assigns the next free type ID to it.
/// Creates a new tag type (atom) and assigns the next free type ID to it.
#define CAF_ADD_ATOM
(project_name, atom_namespace, atom_name)
\
#define CAF_ADD_ATOM
_3(project_name, atom_namespace, atom_name)
\
namespace atom_namespace { \
namespace atom_namespace { \
struct atom_name {}; \
struct atom_name {}; \
static constexpr atom_name atom_name##_v = atom_name{}; \
static constexpr atom_name atom_name##_v = atom_name{}; \
...
@@ -138,6 +156,15 @@ constexpr type_id_t first_custom_type_id = 200;
...
@@ -138,6 +156,15 @@ constexpr type_id_t first_custom_type_id = 200;
} \
} \
CAF_ADD_TYPE_ID(project_name, atom_namespace ::atom_name)
CAF_ADD_TYPE_ID(project_name, atom_namespace ::atom_name)
#ifdef CAF_MSVC
# define CAF_ADD_ATOM(...) \
CAF_PP_CAT(CAF_PP_OVERLOAD(CAF_ADD_ATOM_, __VA_ARGS__)(__VA_ARGS__), \
CAF_PP_EMPTY())
#else
# define CAF_ADD_ATOM(...) \
CAF_PP_OVERLOAD(CAF_ADD_ATOM_, __VA_ARGS__)(__VA_ARGS__)
#endif
/// Finalizes a code block for registering custom types to CAF. Stores the last
/// Finalizes a code block for registering custom types to CAF. Stores the last
/// type ID used by the project as `caf::${project_name}_last_type_id`.
/// type ID used by the project as `caf::${project_name}_last_type_id`.
#define CAF_END_TYPE_ID_BLOCK(project_name) \
#define CAF_END_TYPE_ID_BLOCK(project_name) \
...
...
libcaf_core/caf/type_id_list.hpp
View file @
71c043cc
...
@@ -53,13 +53,16 @@ public:
...
@@ -53,13 +53,16 @@ public:
}
}
/// Returns the number of elements in the list.
/// Returns the number of elements in the list.
/// @pre `data() != nullptr`
constexpr
size_t
size
()
const
noexcept
{
constexpr
size_t
size
()
const
noexcept
{
return
data_
[
0
];
return
data_
[
0
];
}
}
/// Returns `size() == 0`.
constexpr
bool
empty
()
const
noexcept
{
return
size
()
==
0
;
}
/// Returns the type ID at `index`.
/// Returns the type ID at `index`.
/// @pre `data() != nullptr`
constexpr
type_id_t
operator
[](
size_t
index
)
const
noexcept
{
constexpr
type_id_t
operator
[](
size_t
index
)
const
noexcept
{
return
data_
[
index
+
1
];
return
data_
[
index
+
1
];
}
}
...
@@ -86,14 +89,14 @@ private:
...
@@ -86,14 +89,14 @@ private:
/// @private
/// @private
template
<
class
...
Ts
>
template
<
class
...
Ts
>
struct
make_type_id_list_helper
{
struct
make_type_id_list_helper
{
static
constexpr
inline
type_id_t
data
[]
static
inline
type_id_t
data
[]
=
{
static_cast
<
type_id_t
>
(
sizeof
...(
Ts
)),
=
{
static_cast
<
type_id_t
>
(
sizeof
...(
Ts
)),
type_id_v
<
Ts
>
...};
type_id_v
<
Ts
>
...};
};
};
/// Constructs a ::type_id_list from the template parameter pack `Ts`.
/// Constructs a ::type_id_list from the template parameter pack `Ts`.
/// @relates type_id_list
/// @relates type_id_list
template
<
class
...
Ts
>
template
<
class
...
Ts
>
constexpr
type_id_list
make_type_id_list
()
{
type_id_list
make_type_id_list
()
{
return
type_id_list
{
make_type_id_list_helper
<
Ts
...
>::
data
};
return
type_id_list
{
make_type_id_list_helper
<
Ts
...
>::
data
};
}
}
...
...
libcaf_core/src/binary_deserializer.cpp
View file @
71c043cc
...
@@ -68,14 +68,8 @@ binary_deserializer::binary_deserializer(actor_system& sys) noexcept
...
@@ -68,14 +68,8 @@ binary_deserializer::binary_deserializer(actor_system& sys) noexcept
// nop
// nop
}
}
result_type
binary_deserializer
::
begin_object
(
uint16_t
&
nr
,
std
::
string
&
name
)
{
result_type
binary_deserializer
::
begin_object
(
type_id_t
&
type
)
{
name
.
clear
();
return
apply
(
type
);
if
(
auto
err
=
apply
(
nr
))
return
err
;
if
(
nr
==
0
)
if
(
auto
err
=
apply
(
name
))
return
err
;
return
none
;
}
}
result_type
binary_deserializer
::
end_object
()
noexcept
{
result_type
binary_deserializer
::
end_object
()
noexcept
{
...
...
libcaf_core/src/binary_serializer.cpp
View file @
71c043cc
...
@@ -49,10 +49,8 @@ void binary_serializer::skip(size_t num_bytes) {
...
@@ -49,10 +49,8 @@ void binary_serializer::skip(size_t num_bytes) {
write_pos_
+=
num_bytes
;
write_pos_
+=
num_bytes
;
}
}
error_code
<
sec
>
binary_serializer
::
begin_object
(
uint16_t
nr
,
string_view
name
)
{
error_code
<
sec
>
binary_serializer
::
begin_object
(
type_id_t
type
)
{
apply
(
nr
);
apply
(
type
);
if
(
nr
==
0
)
apply
(
name
);
return
none
;
return
none
;
}
}
...
...
libcaf_core/src/detail/append_hex.cpp
View file @
71c043cc
...
@@ -20,15 +20,15 @@
...
@@ -20,15 +20,15 @@
namespace
caf
::
detail
{
namespace
caf
::
detail
{
void
append_hex
(
std
::
string
&
result
,
const
uint8_t
*
xs
,
size_t
n
)
{
void
append_hex
(
std
::
string
&
result
,
const
byte
*
xs
,
size_t
n
)
{
if
(
n
==
0
)
{
if
(
n
==
0
)
{
result
+=
"
00
"
;
result
+=
"
<empty>
"
;
return
;
return
;
}
}
auto
tbl
=
"0123456789ABCDEF"
;
auto
tbl
=
"0123456789ABCDEF"
;
char
buf
[
3
]
=
{
0
,
0
,
0
};
char
buf
[
3
]
=
{
0
,
0
,
0
};
for
(
size_t
i
=
0
;
i
<
n
;
++
i
)
{
for
(
size_t
i
=
0
;
i
<
n
;
++
i
)
{
auto
c
=
xs
[
i
]
;
auto
c
=
to_integer
<
uint8_t
>
(
xs
[
i
])
;
buf
[
0
]
=
tbl
[
c
>>
4
];
buf
[
0
]
=
tbl
[
c
>>
4
];
buf
[
1
]
=
tbl
[
c
&
0x0F
];
buf
[
1
]
=
tbl
[
c
&
0x0F
];
result
+=
buf
;
result
+=
buf
;
...
...
libcaf_core/src/detail/append_percent_encoded.cpp
View file @
71c043cc
...
@@ -18,6 +18,7 @@
...
@@ -18,6 +18,7 @@
#include "caf/detail/append_percent_encoded.hpp"
#include "caf/detail/append_percent_encoded.hpp"
#include "caf/byte.hpp"
#include "caf/config.hpp"
#include "caf/config.hpp"
#include "caf/detail/append_hex.hpp"
#include "caf/detail/append_hex.hpp"
#include "caf/string_view.hpp"
#include "caf/string_view.hpp"
...
@@ -33,7 +34,7 @@ void append_percent_encoded(std::string& str, string_view x, bool is_path) {
...
@@ -33,7 +34,7 @@ void append_percent_encoded(std::string& str, string_view x, bool is_path) {
str
+=
ch
;
str
+=
ch
;
break
;
break
;
}
}
CAF_ANNOTATE_FALLTHROUGH
;
[[
fallthrough
]]
;
case
' '
:
case
' '
:
case
'?'
:
case
'?'
:
case
'#'
:
case
'#'
:
...
@@ -53,7 +54,7 @@ void append_percent_encoded(std::string& str, string_view x, bool is_path) {
...
@@ -53,7 +54,7 @@ void append_percent_encoded(std::string& str, string_view x, bool is_path) {
case
';'
:
case
';'
:
case
'='
:
case
'='
:
str
+=
'%'
;
str
+=
'%'
;
append_hex
(
str
,
reinterpret_cast
<
uint8_t
*>
(
&
ch
),
1
);
append_hex
(
str
,
reinterpret_cast
<
byte
*>
(
&
ch
),
1
);
break
;
break
;
default:
default:
str
+=
ch
;
str
+=
ch
;
...
...
libcaf_core/src/detail/meta_object.cpp
View file @
71c043cc
...
@@ -76,9 +76,10 @@ span<const meta_object> global_meta_objects() {
...
@@ -76,9 +76,10 @@ span<const meta_object> global_meta_objects() {
return
{
meta_objects
,
meta_objects_size
};
return
{
meta_objects
,
meta_objects_size
};
}
}
meta_object
&
global_meta_object
(
type_id_t
id
)
{
const
meta_object
*
global_meta_object
(
type_id_t
id
)
{
CAF_ASSERT
(
id
<
meta_objects_size
);
CAF_ASSERT
(
id
<
meta_objects_size
);
return
meta_objects
[
id
];
auto
&
meta
=
meta_objects
[
id
];
return
meta
.
type_name
!=
nullptr
?
&
meta
:
nullptr
;
}
}
void
clear_global_meta_objects
()
{
void
clear_global_meta_objects
()
{
...
...
libcaf_core/src/detail/serialized_size.cpp
View file @
71c043cc
...
@@ -26,11 +26,8 @@
...
@@ -26,11 +26,8 @@
namespace
caf
::
detail
{
namespace
caf
::
detail
{
error
serialized_size_inspector
::
begin_object
(
uint16_t
nr
,
string_view
name
)
{
error
serialized_size_inspector
::
begin_object
(
type_id_t
type
)
{
if
(
nr
!=
0
)
return
apply
(
type
);
return
apply
(
nr
);
apply
(
nr
);
return
apply
(
name
);
}
}
error
serialized_size_inspector
::
end_object
()
{
error
serialized_size_inspector
::
end_object
()
{
...
...
libcaf_core/src/inbound_path.cpp
View file @
71c043cc
...
@@ -75,7 +75,7 @@ inbound_path::inbound_path(stream_manager_ptr mgr_ptr, stream_slots id,
...
@@ -75,7 +75,7 @@ inbound_path::inbound_path(stream_manager_ptr mgr_ptr, stream_slots id,
mgr
->
register_input_path
(
this
);
mgr
->
register_input_path
(
this
);
CAF_STREAM_LOG_DEBUG
(
mgr
->
self
()
->
name
()
CAF_STREAM_LOG_DEBUG
(
mgr
->
self
()
->
name
()
<<
"opens input stream with element type"
<<
"opens input stream with element type"
<<
detail
::
global_meta_object
(
in_type
)
.
type_name
<<
detail
::
global_meta_object
(
in_type
)
->
type_name
<<
"at slot"
<<
id
.
receiver
<<
"from"
<<
hdl
);
<<
"at slot"
<<
id
.
receiver
<<
"from"
<<
hdl
);
if
(
auto
str
=
get_if
<
std
::
string
>
(
&
self
()
->
system
().
config
(),
if
(
auto
str
=
get_if
<
std
::
string
>
(
&
self
()
->
system
().
config
(),
"stream.credit-policy"
))
{
"stream.credit-policy"
))
{
...
...
libcaf_core/src/message.cpp
View file @
71c043cc
...
@@ -154,9 +154,28 @@ error_code<sec> inspect(binary_deserializer& source, message& msg) {
...
@@ -154,9 +154,28 @@ error_code<sec> inspect(binary_deserializer& source, message& msg) {
return
msg
.
load
(
source
);
return
msg
.
load
(
source
);
}
}
std
::
string
to_string
(
const
message
&
)
{
std
::
string
to_string
(
const
message
&
msg
)
{
// TODO: implement me
if
(
msg
.
empty
())
return
""
;
return
"<empty-message>"
;
std
::
string
result
;
result
+=
'('
;
auto
types
=
msg
.
types
();
if
(
!
types
.
empty
())
{
auto
ptr
=
msg
.
cdata
().
storage
();
auto
meta
=
detail
::
global_meta_object
(
types
[
0
]);
CAF_ASSERT
(
meta
!=
nullptr
);
meta
->
stringify
(
result
,
ptr
);
ptr
+=
meta
->
padded_size
;
for
(
size_t
index
=
1
;
index
<
types
.
size
();
++
index
)
{
result
+=
", "
;
meta
=
detail
::
global_meta_object
(
types
[
index
]);
CAF_ASSERT
(
meta
!=
nullptr
);
meta
->
stringify
(
result
,
ptr
);
ptr
+=
meta
->
padded_size
;
}
}
result
+=
')'
;
return
result
;
}
}
}
// namespace caf
}
// namespace caf
libcaf_core/src/type_id_list.cpp
View file @
71c043cc
...
@@ -27,10 +27,10 @@ std::string to_string(type_id_list xs) {
...
@@ -27,10 +27,10 @@ std::string to_string(type_id_list xs) {
return
"[]"
;
return
"[]"
;
std
::
string
result
;
std
::
string
result
;
result
+=
'['
;
result
+=
'['
;
result
+=
detail
::
global_meta_object
(
xs
[
0
])
.
type_name
;
result
+=
detail
::
global_meta_object
(
xs
[
0
])
->
type_name
;
for
(
size_t
index
=
1
;
index
<
xs
.
size
();
++
index
)
{
for
(
size_t
index
=
1
;
index
<
xs
.
size
();
++
index
)
{
result
+=
", "
;
result
+=
", "
;
result
+=
detail
::
global_meta_object
(
xs
[
index
])
.
type_name
;
result
+=
detail
::
global_meta_object
(
xs
[
index
])
->
type_name
;
}
}
result
+=
']'
;
result
+=
']'
;
return
result
;
return
result
;
...
...
libcaf_core/test/detail/meta_object.cpp
View file @
71c043cc
...
@@ -160,7 +160,7 @@ CAF_TEST(resizing the global meta objects keeps entries) {
...
@@ -160,7 +160,7 @@ CAF_TEST(resizing the global meta objects keeps entries) {
CAF_CHECK_EQUAL
(
xs2
.
size
(),
2u
);
CAF_CHECK_EQUAL
(
xs2
.
size
(),
2u
);
CAF_CHECK
(
eq
(
xs2
[
0
],
meta_i32
));
CAF_CHECK
(
eq
(
xs2
[
0
],
meta_i32
));
resize_global_meta_objects
(
3
);
resize_global_meta_objects
(
3
);
CAF_CHECK
(
eq
(
global_meta_object
(
0
),
meta_i32
));
CAF_CHECK
(
eq
(
*
global_meta_object
(
0
),
meta_i32
));
}
}
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
)
{
...
@@ -180,11 +180,11 @@ CAF_TEST(init_global_meta_objects takes care of creating a meta object table) {
...
@@ -180,11 +180,11 @@ CAF_TEST(init_global_meta_objects takes care of creating a meta object table) {
};
};
CAF_CHECK
(
std
::
equal
(
xs
.
begin
(),
xs
.
end
(),
ys
.
begin
(),
ys
.
end
(),
same
));
CAF_CHECK
(
std
::
equal
(
xs
.
begin
(),
xs
.
end
(),
ys
.
begin
(),
ys
.
end
(),
same
));
CAF_MESSAGE
(
"init_global_meta_objects can initialize allocated chunks"
);
CAF_MESSAGE
(
"init_global_meta_objects can initialize allocated chunks"
);
CAF_CHECK_EQUAL
(
global_meta_object
(
type_id_v
<
float
>
)
.
type_name
,
nullptr
);
CAF_CHECK_EQUAL
(
global_meta_object
(
type_id_v
<
float
>
)
->
type_name
,
nullptr
);
init_global_meta_objects
<
builtin_type_ids
>
();
init_global_meta_objects
<
builtin_type_ids
>
();
CAF_MESSAGE
(
"again, calling init_global_meta_objects again is a no-op"
);
CAF_MESSAGE
(
"again, calling init_global_meta_objects again is a no-op"
);
init_global_meta_objects
<
builtin_type_ids
>
();
init_global_meta_objects
<
builtin_type_ids
>
();
CAF_CHECK_EQUAL
(
global_meta_object
(
type_id_v
<
float
>
)
.
type_name
,
"float"
s
);
CAF_CHECK_EQUAL
(
global_meta_object
(
type_id_v
<
float
>
)
->
type_name
,
"float"
s
);
}
}
CAF_TEST_FIXTURE_SCOPE_END
()
CAF_TEST_FIXTURE_SCOPE_END
()
libcaf_core/test/message.cpp
View file @
71c043cc
...
@@ -30,6 +30,7 @@
...
@@ -30,6 +30,7 @@
#include "caf/init_global_meta_objects.hpp"
#include "caf/init_global_meta_objects.hpp"
#include "caf/message_handler.hpp"
#include "caf/message_handler.hpp"
#include "caf/type_id.hpp"
#include "caf/type_id.hpp"
#include "caf/type_id_list.hpp"
namespace
{
namespace
{
...
@@ -118,6 +119,17 @@ struct config : actor_system_config {
...
@@ -118,6 +119,17 @@ struct config : actor_system_config {
CAF_TEST_FIXTURE_SCOPE
(
message_tests
,
test_coordinator_fixture
<
config
>
)
CAF_TEST_FIXTURE_SCOPE
(
message_tests
,
test_coordinator_fixture
<
config
>
)
CAF_TEST
(
messages
allow
index
-
based
access
)
{
auto
msg
=
make_message
(
"abc"
,
uint32_t
{
10
},
20.0
);
CAF_CHECK_EQUAL
(
msg
.
size
(),
3u
);
CAF_CHECK_EQUAL
(
msg
.
types
(),
(
make_type_id_list
<
std
::
string
,
uint32_t
,
double
>
()));
CAF_CHECK_EQUAL
(
msg
.
get_as
<
std
::
string
>
(
0
),
"abc"
);
CAF_CHECK_EQUAL
(
msg
.
get_as
<
uint32_t
>
(
1
),
10u
);
CAF_CHECK_EQUAL
(
msg
.
get_as
<
double
>
(
2
),
20.0
);
CAF_CHECK_EQUAL
(
msg
.
cdata
().
get_reference_count
(),
1u
);
}
CAF_TEST
(
compare_custom_types
)
{
CAF_TEST
(
compare_custom_types
)
{
s2
tmp
;
s2
tmp
;
tmp
.
value
[
0
][
1
]
=
100
;
tmp
.
value
[
0
][
1
]
=
100
;
...
@@ -127,15 +139,22 @@ CAF_TEST(compare_custom_types) {
...
@@ -127,15 +139,22 @@ CAF_TEST(compare_custom_types) {
CAF_TEST
(
empty_to_string
)
{
CAF_TEST
(
empty_to_string
)
{
message
msg
;
message
msg
;
CAF_CHECK
(
to_string
(
msg
),
"<empty-message>"
);
CAF_CHECK
_EQUAL
(
to_string
(
msg
),
"<empty-message>"
);
}
}
CAF_TEST
(
integers_to_string
)
{
CAF_TEST
(
integers_to_string
)
{
using
ivec
=
vector
<
int
>
;
using
ivec
=
vector
<
int
32_t
>
;
CAF_CHECK_EQUAL
(
msg_as_string
(
1
,
2
,
3
),
"(1, 2, 3)"
);
CAF_CHECK_EQUAL
(
msg_as_string
(
1
,
2
,
3
),
"(1, 2, 3)"
);
CAF_CHECK_EQUAL
(
msg_as_string
(
ivec
{
1
,
2
,
3
}),
"([1, 2, 3])"
);
CAF_CHECK_EQUAL
(
msg_as_string
(
ivec
{
1
,
2
,
3
}),
"([1, 2, 3])"
);
CAF_CHECK_EQUAL
(
msg_as_string
(
ivec
{
1
,
2
},
3
,
4
,
ivec
{
5
,
6
,
7
}),
CAF_CHECK_EQUAL
(
msg_as_string
(
ivec
{
1
,
2
},
3
,
4
,
ivec
{
5
,
6
,
7
}),
"([1, 2], 3, 4, [5, 6, 7])"
);
"([1, 2], 3, 4, [5, 6, 7])"
);
auto
msg
=
make_message
(
ivec
{
1
,
2
,
3
});
CAF_MESSAGE
(
"s1: "
<<
type_id_v
<
s1
>
);
CAF_MESSAGE
(
"ivec: "
<<
type_id_v
<
ivec
>
);
CAF_MESSAGE
(
"msg.types: "
<<
msg
.
types
());
CAF_MESSAGE
(
"types #1: "
<<
make_type_id_list
<
s1
>
());
CAF_MESSAGE
(
"types #2: "
<<
make_type_id_list
<
ivec
>
());
CAF_CHECK_EQUAL
(
msg
.
get_as
<
ivec
>
(
0
),
ivec
({
1
,
2
,
3
}));
}
}
CAF_TEST
(
strings_to_string
)
{
CAF_TEST
(
strings_to_string
)
{
...
...
manual/ConfiguringActorApplications.rst
View file @
71c043cc
...
@@ -187,29 +187,40 @@ Adding Custom Message Types
...
@@ -187,29 +187,40 @@ Adding Custom Message Types
---------------------------
---------------------------
CAF requires serialization support for all of its message types (see
CAF requires serialization support for all of its message types (see
:ref:`type-inspection`). However, CAF also needs a mapping of unique type
names
:ref:`type-inspection`). However, CAF also needs a mapping of unique type
IDs to
to
user-defined types at runtime. This is required to deserialize arbitrary
user-defined types at runtime. This is required to deserialize arbitrary
messages from the network.
messages from the network.
As an introductory example, we (again) use the following POD type
The type IDs are assigned by listing all custom types in a *type ID block*. CAF
``foo``.
assigns ascending IDs to each type by in the block as well as storing the type
name. In the following example, we forward-declare the types ``foo`` and
``foo2`` and register them to CAF in a *type ID block*. The name of the type ID
block is arbitrary, but it must be a valid C++ identifier.
.. literalinclude:: /examples/custom_type/custom_types_1.cpp
.. literalinclude:: /examples/custom_type/custom_types_1.cpp
:language: C++
:language: C++
:lines: 24-27
:start-after: --(rst-type-id-block-begin)--
:end-before: --(rst-type-id-block-end)--
To make ``foo`` serializable, we make it inspectable:
Aside from a type ID, CAF also requires an ``inspect`` overload in order to be
able to serialize objects. As an introductory example, we (again) use the
following POD type ``foo``.
.. literalinclude:: /examples/custom_type/custom_types_1.cpp
.. literalinclude:: /examples/custom_type/custom_types_1.cpp
:language: C++
:language: C++
:lines: 30-34
:start-after: --(rst-foo-begin)--
:end-before: --(rst-foo-end)--
Finally, we give ``foo`` a platform-neutral name and add it to the list
By assigning type IDs and providing ``inspect`` overloads, we provide static and
of serializable types by using a custom config class.
compile-time information for all our types. However, CAF also needs some
information at run-time for deserializing received data. The function
``init_global_meta_objects`` takes care fo registering all the state we need at
run-time.
.. literalinclude:: /examples/custom_type/custom_types_1.cpp
.. literalinclude:: /examples/custom_type/custom_types_1.cpp
:language: C++
:language: C++
:lines: 75-78,81-84
:start-after: --(rst-config-begin)--
:end-before: --(rst-config-end)--
Adding Custom Error Types
Adding Custom Error Types
-------------------------
-------------------------
...
@@ -231,18 +242,14 @@ simple ``calculator`` actor.
...
@@ -231,18 +242,14 @@ simple ``calculator`` actor.
.. literalinclude:: /examples/remoting/remote_spawn.cpp
.. literalinclude:: /examples/remoting/remote_spawn.cpp
:language: C++
:language: C++
:lines: 33-34
:start-after: --(rst-calculator-begin)--
:end-before: --(rst-calculator-end)--
Adding the calculator actor type to our config is achieved by calling
Adding the calculator actor type to our config is achieved by calling
``add_actor_type<T>``. Note that adding an actor type in this way
``add_actor_type``. After calling this in our config, we can spawn the
implicitly calls ``add_message_type<T>`` for typed actors
``calculator`` anywhere in the distributed actor system (assuming all nodes use
add-custom-message-type_. This makes our ``calculator`` actor type
the same config). Note that the handle type still requires a type ID (see
serializable and also enables remote nodes to spawn calculators anywhere in the
add-custom-message-type_).
distributed actor system (assuming all nodes use the same config).
.. literalinclude:: /examples/remoting/remote_spawn.cpp
:language: C++
:lines: 98-109
Our final example illustrates how to spawn a ``calculator`` locally by
Our final example illustrates how to spawn a ``calculator`` locally by
using its type name. Because the dynamic type name lookup can fail and the
using its type name. Because the dynamic type name lookup can fail and the
...
...
manual/RemoteSpawn.rst
View file @
71c043cc
...
@@ -10,7 +10,8 @@ named "calculator".
...
@@ -10,7 +10,8 @@ named "calculator".
.. literalinclude:: /examples/remoting/remote_spawn.cpp
.. literalinclude:: /examples/remoting/remote_spawn.cpp
:language: C++
:language: C++
:lines: 123-137
:start-after: --(rst-client-begin)--
:end-before: --(rst-client-end)--
We first connect to a CAF node with ``middleman().connect(...)``. On success,
We first connect to a CAF node with ``middleman().connect(...)``. On success,
``connect`` returns the node ID we need for ``remote_spawn``. This requires the
``connect`` returns the node ID we need for ``remote_spawn``. This requires the
...
...
manual/Streaming.rst
View file @
71c043cc
...
@@ -69,7 +69,8 @@ Defining Sources
...
@@ -69,7 +69,8 @@ Defining Sources
.. literalinclude:: /examples/streaming/integer_stream.cpp
.. literalinclude:: /examples/streaming/integer_stream.cpp
:language: C++
:language: C++
:lines: 17-48
:start-after: --(rst-source-begin)--
:end-before: --(rst-source-end)--
The simplest way to defining a source is to use the
The simplest way to defining a source is to use the
``attach_stream_source`` function and pass it four arguments: a pointer
``attach_stream_source`` function and pass it four arguments: a pointer
...
@@ -81,7 +82,8 @@ Defining Stages
...
@@ -81,7 +82,8 @@ Defining Stages
.. literalinclude:: /examples/streaming/integer_stream.cpp
.. literalinclude:: /examples/streaming/integer_stream.cpp
:language: C++
:language: C++
:lines: 50-83
:start-after: --(rst-stage-begin)--
:end-before: --(rst-stage-end)--
The function ``make_stage`` also takes three lambdas but additionally
The function ``make_stage`` also takes three lambdas but additionally
the received input stream handshake as first argument. Instead of a predicate,
the received input stream handshake as first argument. Instead of a predicate,
...
@@ -93,7 +95,8 @@ Defining Sinks
...
@@ -93,7 +95,8 @@ Defining Sinks
.. literalinclude:: /examples/streaming/integer_stream.cpp
.. literalinclude:: /examples/streaming/integer_stream.cpp
:language: C++
:language: C++
:lines: 85-114
:start-after: --(rst-sink-begin)--
:end-before: --(rst-sink-end)--
The function ``make_sink`` is similar to ``make_stage``, except
The function ``make_sink`` is similar to ``make_stage``, except
that is does not produce outputs.
that is does not produce outputs.
...
@@ -103,7 +106,8 @@ Initiating Streams
...
@@ -103,7 +106,8 @@ Initiating Streams
.. literalinclude:: /examples/streaming/integer_stream.cpp
.. literalinclude:: /examples/streaming/integer_stream.cpp
:language: C++
:language: C++
:lines: 128-132
:start-after: --(rst-main-begin)--
:end-before: --(rst-main-end)--
In our example, we always have a source ``int_source`` and a sink
In our example, we always have a source ``int_source`` and a sink
``int_sink`` with an optional stage ``int_selector``. Sending
``int_sink`` with an optional stage ``int_selector``. Sending
...
...
manual/TypeInspection.rst
View file @
71c043cc
...
@@ -49,10 +49,9 @@ implementing a hash function.
...
@@ -49,10 +49,9 @@ implementing a hash function.
Inspector {
Inspector {
using result_type = T;
using result_type = T;
if (inspector only requires read access to the state of T)
static constexpr bool reads_state = ...;
static constexpr bool reads_state = true;
else
static constexpr bool writes_state = ...;
static constexpr bool writes_state = true;
template <class... Ts>
template <class... Ts>
result_type operator()(Ts&&...);
result_type operator()(Ts&&...);
...
@@ -116,7 +115,8 @@ access to its members.
...
@@ -116,7 +115,8 @@ access to its members.
.. literalinclude:: /examples/custom_type/custom_types_3.cpp
.. literalinclude:: /examples/custom_type/custom_types_3.cpp
:language: C++
:language: C++
:lines: 20-49
:start-after: --(rst-foo-begin)--
:end-before: --(rst-foo-end)--
Since there is no access to the data fields ``a_`` and ``b_``
Since there is no access to the data fields ``a_`` and ``b_``
(and assuming no changes to ``foo`` are possible), we need to split our
(and assuming no changes to ``foo`` are possible), we need to split our
...
@@ -124,7 +124,8 @@ implementation of ``inspect`` as shown below.
...
@@ -124,7 +124,8 @@ implementation of ``inspect`` as shown below.
.. literalinclude:: /examples/custom_type/custom_types_3.cpp
.. literalinclude:: /examples/custom_type/custom_types_3.cpp
:language: C++
:language: C++
:lines: 76-103
:start-after: --(rst-inspect-begin)--
:end-before: --(rst-inspect-end)--
The purpose of the scope guard in the example above is to write the content of
The purpose of the scope guard in the example above is to write the content of
the temporaries back to ``foo`` at scope exit automatically. Storing
the temporaries back to ``foo`` at scope exit automatically. Storing
...
...
tools/caf-vec.cpp
View file @
71c043cc
...
@@ -8,6 +8,17 @@
...
@@ -8,6 +8,17 @@
#include "caf/all.hpp"
#include "caf/all.hpp"
struct
entity
;
struct
se_event
;
CAF_BEGIN_TYPE_ID_BLOCK
(
caf_vec
,
first_custom_type_id
)
CAF_ADD_TYPE_ID
(
caf_vec
,
entity
);
CAF_ADD_TYPE_ID
(
caf_vec
,
se_event
);
CAF_END_TYPE_ID_BLOCK
(
caf_vec
)
using
std
::
string
;
using
std
::
string
;
using
namespace
caf
;
using
namespace
caf
;
...
@@ -739,6 +750,7 @@ struct config : public actor_system_config {
...
@@ -739,6 +750,7 @@ 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"
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment