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
3ce764a9
Commit
3ce764a9
authored
Jan 31, 2014
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
re-implemented sync_send for typed actors
parent
5e5ccb08
Changes
16
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
690 additions
and
480 deletions
+690
-480
cppa.files
cppa.files
+2
-2
cppa/actor.hpp
cppa/actor.hpp
+2
-0
cppa/behavior_stack_based.hpp
cppa/behavior_stack_based.hpp
+90
-39
cppa/blocking_actor.hpp
cppa/blocking_actor.hpp
+6
-95
cppa/event_based_actor.hpp
cppa/event_based_actor.hpp
+5
-70
cppa/io/broker.hpp
cppa/io/broker.hpp
+2
-1
cppa/local_actor.hpp
cppa/local_actor.hpp
+3
-1
cppa/response_handle.hpp
cppa/response_handle.hpp
+99
-57
cppa/spawn.hpp
cppa/spawn.hpp
+21
-2
cppa/sync_sender.hpp
cppa/sync_sender.hpp
+332
-0
cppa/typed_actor.hpp
cppa/typed_actor.hpp
+28
-5
cppa/typed_behavior.hpp
cppa/typed_behavior.hpp
+5
-5
cppa/typed_behavior_stack_based.hpp
cppa/typed_behavior_stack_based.hpp
+0
-131
cppa/typed_continue_helper.hpp
cppa/typed_continue_helper.hpp
+20
-47
cppa/typed_event_based_actor.hpp
cppa/typed_event_based_actor.hpp
+11
-5
unit_testing/test_typed_spawn.cpp
unit_testing/test_typed_spawn.cpp
+64
-20
No files found.
cppa.files
View file @
3ce764a9
...
@@ -174,10 +174,8 @@ cppa/tpartial_function.hpp
...
@@ -174,10 +174,8 @@ cppa/tpartial_function.hpp
cppa/tuple_cast.hpp
cppa/tuple_cast.hpp
cppa/type_lookup_table.hpp
cppa/type_lookup_table.hpp
cppa/typed_actor.hpp
cppa/typed_actor.hpp
cppa/typed_actor_base.hpp
cppa/typed_actor_ptr.hpp
cppa/typed_actor_ptr.hpp
cppa/typed_behavior.hpp
cppa/typed_behavior.hpp
cppa/typed_behavior_stack_based.hpp
cppa/typed_event_based_actor.hpp
cppa/typed_event_based_actor.hpp
cppa/uniform_type_info.hpp
cppa/uniform_type_info.hpp
cppa/unit.hpp
cppa/unit.hpp
...
@@ -347,3 +345,5 @@ unit_testing/test_tuple.cpp
...
@@ -347,3 +345,5 @@ unit_testing/test_tuple.cpp
unit_testing/test_typed_spawn.cpp
unit_testing/test_typed_spawn.cpp
unit_testing/test_uniform_type.cpp
unit_testing/test_uniform_type.cpp
unit_testing/test_yield_interface.cpp
unit_testing/test_yield_interface.cpp
cppa/typed_continue_helper.hpp
cppa/sync_sender.hpp
cppa/actor.hpp
View file @
3ce764a9
...
@@ -46,6 +46,7 @@ namespace cppa {
...
@@ -46,6 +46,7 @@ namespace cppa {
class
actor_addr
;
class
actor_addr
;
class
actor_proxy
;
class
actor_proxy
;
class
local_actor
;
class
blocking_actor
;
class
blocking_actor
;
class
event_based_actor
;
class
event_based_actor
;
...
@@ -87,6 +88,7 @@ class actor : util::comparable<actor>
...
@@ -87,6 +88,7 @@ class actor : util::comparable<actor>
,
util
::
comparable
<
actor
,
invalid_actor_t
>
,
util
::
comparable
<
actor
,
invalid_actor_t
>
,
util
::
comparable
<
actor
,
invalid_actor_addr_t
>
{
,
util
::
comparable
<
actor
,
invalid_actor_addr_t
>
{
friend
class
local_actor
;
friend
class
detail
::
raw_access
;
friend
class
detail
::
raw_access
;
public:
public:
...
...
cppa/behavior_stack_based.hpp
View file @
3ce764a9
...
@@ -33,52 +33,74 @@
...
@@ -33,52 +33,74 @@
#include "cppa/message_id.hpp"
#include "cppa/message_id.hpp"
#include "cppa/single_timeout.hpp"
#include "cppa/single_timeout.hpp"
#include "cppa/typed_behavior.hpp"
#include "cppa/behavior_policy.hpp"
#include "cppa/behavior_policy.hpp"
#include "cppa/response_handle.hpp"
#include "cppa/detail/behavior_stack.hpp"
#include "cppa/detail/behavior_stack.hpp"
namespace
cppa
{
namespace
cppa
{
/**
template
<
class
Base
,
class
Subtype
,
class
BehaviorType
>
* @brief Mixin for actors using a stack-based message processing.
class
behavior_stack_based_impl
:
public
single_timeout
<
Base
,
Subtype
>
{
* @note This mixin implicitly includes {@link single_timeout}.
*/
template
<
class
Base
,
class
Subtype
>
class
behavior_stack_based
:
public
single_timeout
<
Base
,
Subtype
>
{
typedef
single_timeout
<
Base
,
Subtype
>
super
;
typedef
single_timeout
<
Base
,
Subtype
>
super
;
public:
public:
typedef
behavior_stack_based
combined_type
;
/**************************************************************************
* typedefs and constructor *
**************************************************************************/
typedef
BehaviorType
behavior_type
;
typedef
behavior_stack_based_impl
combined_type
;
typedef
response_handle
<
behavior_stack_based_impl
,
any_tuple
,
nonblocking_response_handle_tag
>
response_handle_type
;
template
<
typename
...
Ts
>
template
<
typename
...
Ts
>
behavior_stack_based
(
Ts
&&
...
args
)
:
super
(
std
::
forward
<
Ts
>
(
arg
s
)...)
{
}
behavior_stack_based
_impl
(
Ts
&&
...
vs
)
:
super
(
std
::
forward
<
Ts
>
(
v
s
)...)
{
}
inline
void
unbecome
()
{
/**************************************************************************
m_bhvr_stack
.
pop_async_back
();
* become() member function family *
**************************************************************************/
void
become
(
behavior_type
bhvr
)
{
do_become
(
std
::
move
(
bhvr
),
true
);
}
template
<
bool
Discard
>
void
become
(
behavior_policy
<
Discard
>
,
behavior_type
bhvr
)
{
do_become
(
std
::
move
(
bhvr
),
Discard
);
}
}
/**
* @brief Sets the actor's behavior and discards the previous behavior
* unless {@link keep_behavior} is given as first argument.
*/
template
<
typename
T
,
typename
...
Ts
>
template
<
typename
T
,
typename
...
Ts
>
inline
typename
std
::
enable_if
<
inline
typename
std
::
enable_if
<
!
is_behavior_policy
<
typename
util
::
rm_const_and_ref
<
T
>::
type
>::
value
,
!
is_behavior_policy
<
typename
util
::
rm_const_and_ref
<
T
>::
type
>::
value
,
void
void
>::
type
>::
type
become
(
T
&&
arg
,
Ts
&&
...
args
)
{
become
(
T
&&
arg
,
Ts
&&
...
args
)
{
do_become
(
match_expr_convert
(
std
::
forward
<
T
>
(
arg
),
do_become
(
behavior_type
{
std
::
forward
<
T
>
(
arg
),
std
::
forward
<
Ts
>
(
args
)...)
,
std
::
forward
<
Ts
>
(
args
)...}
,
true
);
true
);
}
}
template
<
bool
Discard
,
typename
...
Ts
>
template
<
bool
Discard
,
typename
...
Ts
>
inline
void
become
(
behavior_policy
<
Discard
>
,
Ts
&&
...
args
)
{
void
become
(
behavior_policy
<
Discard
>
,
Ts
&&
...
args
)
{
do_become
(
match_expr_convert
(
std
::
forward
<
Ts
>
(
args
)...)
,
Discard
);
do_become
(
behavior_type
{
std
::
forward
<
Ts
>
(
args
)...}
,
Discard
);
}
}
inline
void
unbecome
()
{
m_bhvr_stack
.
pop_async_back
();
}
/**************************************************************************
* convenience member function for stack manipulation *
**************************************************************************/
inline
bool
has_behavior
()
const
{
inline
bool
has_behavior
()
const
{
return
m_bhvr_stack
.
empty
()
==
false
;
return
m_bhvr_stack
.
empty
()
==
false
;
}
}
...
@@ -88,10 +110,6 @@ class behavior_stack_based : public single_timeout<Base, Subtype> {
...
@@ -88,10 +110,6 @@ class behavior_stack_based : public single_timeout<Base, Subtype> {
return
m_bhvr_stack
.
back
();
return
m_bhvr_stack
.
back
();
}
}
inline
detail
::
behavior_stack
&
bhvr_stack
()
{
return
m_bhvr_stack
;
}
optional
<
behavior
&>
sync_handler
(
message_id
msg_id
)
override
{
optional
<
behavior
&>
sync_handler
(
message_id
msg_id
)
override
{
return
m_bhvr_stack
.
sync_handler
(
msg_id
);
return
m_bhvr_stack
.
sync_handler
(
msg_id
);
}
}
...
@@ -100,38 +118,71 @@ class behavior_stack_based : public single_timeout<Base, Subtype> {
...
@@ -100,38 +118,71 @@ class behavior_stack_based : public single_timeout<Base, Subtype> {
m_bhvr_stack
.
erase
(
mid
);
m_bhvr_stack
.
erase
(
mid
);
}
}
void
become_waiting_for
(
behavior
bhvr
,
message_id
mf
)
{
inline
detail
::
behavior_stack
&
bhvr_stack
()
{
//CPPA_LOG_TRACE(CPPA_MARG(mf, integer_value));
return
m_bhvr_stack
;
if
(
bhvr
.
timeout
().
valid
())
{
if
(
bhvr
.
timeout
().
valid
())
{
this
->
reset_timeout
();
this
->
request_timeout
(
bhvr
.
timeout
());
}
this
->
bhvr_stack
().
push_back
(
std
::
move
(
bhvr
),
mf
);
}
this
->
bhvr_stack
().
push_back
(
std
::
move
(
bhvr
),
mf
);
}
}
void
do_become
(
behavior
bhvr
,
bool
discard_old
)
{
private:
//CPPA_LOG_TRACE(CPPA_ARG(discard_old));
//if (discard_old) m_bhvr_stack.pop_async_back();
void
do_become
(
behavior_type
bhvr
,
bool
discard_old
)
{
//m_bhvr_stack.push_back(std::move(bhvr));
if
(
discard_old
)
this
->
m_bhvr_stack
.
pop_async_back
();
if
(
discard_old
)
this
->
m_bhvr_stack
.
pop_async_back
();
this
->
reset_timeout
();
this
->
reset_timeout
();
if
(
bhvr
.
timeout
().
valid
())
{
if
(
bhvr
.
timeout
().
valid
())
{
//CPPA_LOG_DEBUG("request timeout: " << bhvr.timeout().to_string());
this
->
request_timeout
(
bhvr
.
timeout
());
this
->
request_timeout
(
bhvr
.
timeout
());
}
}
this
->
m_bhvr_stack
.
push_back
(
std
::
move
(
bhvr
));
this
->
m_bhvr_stack
.
push_back
(
std
::
move
(
unbox
(
bhvr
)));
}
static
inline
behavior
&
unbox
(
behavior
&
arg
)
{
return
arg
;
}
template
<
typename
...
Ts
>
static
inline
behavior
&
unbox
(
typed_behavior
<
Ts
...
>&
arg
)
{
return
arg
.
unbox
();
}
// utility for getting a pointer-to-derived-type
Subtype
*
dptr
()
{
return
static_cast
<
Subtype
*>
(
this
);
}
}
protected:
// utility for getting a const pointer-to-derived-type
const
Subtype
*
dptr
()
const
{
return
static_cast
<
const
Subtype
*>
(
this
);
}
// allows actors to keep previous behaviors and enables unbecome()
// allows actors to keep previous behaviors and enables unbecome()
detail
::
behavior_stack
m_bhvr_stack
;
detail
::
behavior_stack
m_bhvr_stack
;
};
};
/**
* @brief Mixin for actors using a stack-based message processing.
* @note This mixin implicitly includes {@link single_timeout}.
*/
template
<
class
BehaviorType
>
class
behavior_stack_based
{
public:
template
<
class
Base
,
class
Subtype
>
class
impl
:
public
behavior_stack_based_impl
<
Base
,
Subtype
,
BehaviorType
>
{
typedef
behavior_stack_based_impl
<
Base
,
Subtype
,
BehaviorType
>
super
;
public:
typedef
impl
combined_type
;
template
<
typename
...
Ts
>
impl
(
Ts
&&
...
args
)
:
super
(
std
::
forward
<
Ts
>
(
args
)...)
{
}
};
};
}
// namespace cppa
}
// namespace cppa
#endif // CPPA_BEHAVIOR_STACK_BASED_HPP
#endif // CPPA_BEHAVIOR_STACK_BASED_HPP
cppa/blocking_actor.hpp
View file @
3ce764a9
...
@@ -34,14 +34,13 @@
...
@@ -34,14 +34,13 @@
#include "cppa/on.hpp"
#include "cppa/on.hpp"
#include "cppa/extend.hpp"
#include "cppa/extend.hpp"
#include "cppa/behavior.hpp"
#include "cppa/behavior.hpp"
#include "cppa/typed_actor.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/sync_sender.hpp"
#include "cppa/typed_actor.hpp"
#include "cppa/mailbox_based.hpp"
#include "cppa/mailbox_based.hpp"
#include "cppa/mailbox_element.hpp"
#include "cppa/mailbox_element.hpp"
#include "cppa/response_handle.hpp"
#include "cppa/response_handle.hpp"
#include "cppa/detail/response_handle_util.hpp"
namespace
cppa
{
namespace
cppa
{
/**
/**
...
@@ -49,101 +48,13 @@ namespace cppa {
...
@@ -49,101 +48,13 @@ namespace cppa {
* receive rather than a behavior-stack based message processing.
* receive rather than a behavior-stack based message processing.
* @extends local_actor
* @extends local_actor
*/
*/
class
blocking_actor
:
public
extend
<
local_actor
>::
with
<
mailbox_based
>
{
class
blocking_actor
:
public
extend
<
local_actor
,
blocking_actor
>::
with
<
mailbox_based
,
sync_sender
<
blocking_response_handle_tag
>::
impl
>
{
public:
public:
typedef
blocking_response_handle_tag
response_handle_tag
;
typedef
response_handle
<
blocking_actor
>
response_handle_type
;
/**************************************************************************
* sync_send[_tuple](actor, ...) *
**************************************************************************/
/**
* @brief Sends @p what as a synchronous message to @p whom.
* @param whom Receiver of the message.
* @param what Message content as tuple.
* @returns A handle identifying a future to the response of @p whom.
* @warning The returned handle is actor specific and the response to the
* sent message cannot be received by another actor.
* @throws std::invalid_argument if <tt>whom == nullptr</tt>
*/
inline
response_handle_type
sync_send_tuple
(
message_priority
prio
,
const
actor
&
dest
,
any_tuple
what
)
{
return
{
sync_send_tuple_impl
(
prio
,
dest
,
std
::
move
(
what
)),
this
};
}
inline
response_handle_type
sync_send_tuple
(
const
actor
&
dest
,
any_tuple
what
)
{
return
sync_send_tuple
(
message_priority
::
normal
,
dest
,
std
::
move
(
what
));
}
/**
* @brief Sends <tt>{what...}</tt> as a synchronous message to @p whom.
* @param whom Receiver of the message.
* @param what Message elements.
* @returns A handle identifying a future to the response of @p whom.
* @warning The returned handle is actor specific and the response to the
* sent message cannot be received by another actor.
* @pre <tt>sizeof...(Ts) > 0</tt>
* @throws std::invalid_argument if <tt>whom == nullptr</tt>
*/
template
<
typename
...
Ts
>
inline
response_handle_type
sync_send
(
message_priority
prio
,
const
actor
&
dest
,
Ts
&&
...
what
)
{
static_assert
(
sizeof
...(
Ts
)
>
0
,
"no message to send"
);
return
sync_send_tuple
(
prio
,
dest
,
make_any_tuple
(
std
::
forward
<
Ts
>
(
what
)...));
}
template
<
typename
...
Ts
>
inline
response_handle_type
sync_send
(
const
actor
&
dest
,
Ts
&&
...
what
)
{
static_assert
(
sizeof
...(
Ts
)
>
0
,
"no message to send"
);
return
sync_send_tuple
(
message_priority
::
normal
,
dest
,
make_any_tuple
(
std
::
forward
<
Ts
>
(
what
)...));
}
/**************************************************************************
* timed_sync_send[_tuple](actor, ...) *
**************************************************************************/
inline
response_handle_type
timed_sync_send_tuple
(
const
util
::
duration
&
rtime
,
const
actor
&
dest
,
any_tuple
what
)
{
return
{
timed_sync_send_tuple_impl
(
message_priority
::
normal
,
dest
,
rtime
,
std
::
move
(
what
)),
this
};
}
template
<
typename
...
Ts
>
response_handle_type
timed_sync_send
(
const
actor
&
dest
,
const
util
::
duration
&
rtime
,
Ts
&&
...
what
)
{
static_assert
(
sizeof
...(
Ts
)
>
0
,
"no message to send"
);
return
timed_sync_send_tuple
(
rtime
,
dest
,
make_any_tuple
(
std
::
forward
<
Ts
>
(
what
)...));
}
/**************************************************************************
* sync_send[_tuple](typed_actor<...>, ...) *
**************************************************************************/
template
<
typename
...
Rs
,
typename
...
Ts
>
inline
response_handle_type
sync_send_tuple
(
message_priority
prio
,
const
typed_actor
<
Rs
...
>&
dest
,
cow_tuple
<
Ts
...
>
what
)
{
return
{
sync_send_tuple_impl
(
prio
,
dest
,
std
::
move
(
what
)),
this
};
}
template
<
typename
...
Rs
,
typename
...
Ts
>
inline
response_handle_type
sync_send_tuple
(
const
typed_actor
<
Rs
...
>&
dest
,
cow_tuple
<
Ts
...
>
what
)
{
return
sync_send_tuple
(
message_priority
::
normal
,
dest
,
std
::
move
(
what
));
}
/**************************************************************************
/**************************************************************************
* utility stuff and receive() member function family *
* utility stuff and receive() member function family *
**************************************************************************/
**************************************************************************/
...
...
cppa/event_based_actor.hpp
View file @
3ce764a9
...
@@ -35,6 +35,7 @@
...
@@ -35,6 +35,7 @@
#include "cppa/extend.hpp"
#include "cppa/extend.hpp"
#include "cppa/logging.hpp"
#include "cppa/logging.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/sync_sender.hpp"
#include "cppa/mailbox_based.hpp"
#include "cppa/mailbox_based.hpp"
#include "cppa/response_handle.hpp"
#include "cppa/response_handle.hpp"
#include "cppa/behavior_stack_based.hpp"
#include "cppa/behavior_stack_based.hpp"
...
@@ -54,8 +55,10 @@ class event_based_actor;
...
@@ -54,8 +55,10 @@ class event_based_actor;
*
*
* @extends local_actor
* @extends local_actor
*/
*/
class
event_based_actor
:
public
extend
<
local_actor
>::
class
event_based_actor
:
public
extend
<
local_actor
,
event_based_actor
>::
with
<
mailbox_based
,
behavior_stack_based
>
{
with
<
mailbox_based
,
behavior_stack_based
<
behavior
>::
impl
,
sync_sender
<
nonblocking_response_handle_tag
>::
impl
>
{
protected:
protected:
...
@@ -69,74 +72,6 @@ class event_based_actor : public extend<local_actor>::
...
@@ -69,74 +72,6 @@ class event_based_actor : public extend<local_actor>::
*/
*/
void
forward_to
(
const
actor
&
whom
);
void
forward_to
(
const
actor
&
whom
);
public:
typedef
nonblocking_response_handle_tag
response_handle_tag
;
typedef
response_handle
<
event_based_actor
>
untyped_response_handle
;
/**
* @brief Sends @p what as a synchronous message to @p whom.
* @param whom Receiver of the message.
* @param what Message content as tuple.
* @returns A handle identifying a future to the response of @p whom.
* @warning The returned handle is actor specific and the response to the
* sent message cannot be received by another actor.
* @throws std::invalid_argument if <tt>whom == nullptr</tt>
*/
inline
untyped_response_handle
sync_send_tuple
(
const
actor
&
whom
,
any_tuple
what
)
{
return
{
sync_send_tuple_impl
(
message_priority
::
normal
,
whom
,
std
::
move
(
what
)),
this
};
}
/**
* @brief Sends <tt>{what...}</tt> as a synchronous message to @p whom.
* @param whom Receiver of the message.
* @param what Message elements.
* @returns A handle identifying a future to the response of @p whom.
* @warning The returned handle is actor specific and the response to the
* sent message cannot be received by another actor.
* @pre <tt>sizeof...(Ts) > 0</tt>
* @throws std::invalid_argument if <tt>whom == nullptr</tt>
*/
template
<
typename
...
Ts
>
inline
untyped_response_handle
sync_send
(
const
actor
&
whom
,
Ts
&&
...
what
)
{
static_assert
(
sizeof
...(
Ts
)
>
0
,
"no message to send"
);
return
sync_send_tuple
(
whom
,
make_any_tuple
(
std
::
forward
<
Ts
>
(
what
)...));
}
/**
* @brief Sends a synchronous message with timeout @p rtime to @p whom.
* @param whom Receiver of the message.
* @param rtime Relative time until this messages times out.
* @param what Message content as tuple.
*/
untyped_response_handle
timed_sync_send_tuple
(
const
util
::
duration
&
rtime
,
const
actor
&
whom
,
any_tuple
what
)
{
return
{
timed_sync_send_tuple_impl
(
message_priority
::
normal
,
whom
,
rtime
,
std
::
move
(
what
)),
this
};
}
/**
* @brief Sends a synchronous message with timeout @p rtime to @p whom.
* @param whom Receiver of the message.
* @param rtime Relative time until this messages times out.
* @param what Message elements.
* @pre <tt>sizeof...(Ts) > 0</tt>
*/
template
<
typename
...
Ts
>
untyped_response_handle
timed_sync_send
(
const
actor
&
whom
,
const
util
::
duration
&
rtime
,
Ts
&&
...
what
)
{
static_assert
(
sizeof
...(
Ts
)
>
0
,
"no message to send"
);
return
timed_sync_send_tuple
(
rtime
,
whom
,
make_any_tuple
(
std
::
forward
<
Ts
>
(
what
)...));
}
};
};
}
// namespace cppa
}
// namespace cppa
...
...
cppa/io/broker.hpp
View file @
3ce764a9
...
@@ -62,7 +62,8 @@ broker_ptr init_and_launch(broker_ptr);
...
@@ -62,7 +62,8 @@ broker_ptr init_and_launch(broker_ptr);
* and other components in the network.
* and other components in the network.
* @extends local_actor
* @extends local_actor
*/
*/
class
broker
:
public
extend
<
local_actor
>::
with
<
behavior_stack_based
>
{
class
broker
:
public
extend
<
local_actor
>::
with
<
behavior_stack_based
<
behavior
>::
impl
>
{
friend
class
policy
::
sequential_invoke
;
friend
class
policy
::
sequential_invoke
;
...
...
cppa/local_actor.hpp
View file @
3ce764a9
...
@@ -477,7 +477,9 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
...
@@ -477,7 +477,9 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
const
typed_actor
<
Signatures
...
>&
whom
,
const
typed_actor
<
Signatures
...
>&
whom
,
cow_tuple
<
Ts
...
>&&
what
)
{
cow_tuple
<
Ts
...
>&&
what
)
{
check_typed_input
(
whom
,
what
);
check_typed_input
(
whom
,
what
);
return
sync_send_tuple_impl
(
mp
,
whom
.
m_ptr
,
any_tuple
{
std
::
move
(
what
)});
return
sync_send_tuple_impl
(
mp
,
actor
{
whom
.
m_ptr
.
get
()},
any_tuple
{
std
::
move
(
what
)});
}
}
// returns 0 if last_dequeued() is an asynchronous or sync request message,
// returns 0 if last_dequeued() is an asynchronous or sync request message,
...
...
cppa/response_handle.hpp
View file @
3ce764a9
...
@@ -36,9 +36,11 @@
...
@@ -36,9 +36,11 @@
#include "cppa/message_id.hpp"
#include "cppa/message_id.hpp"
#include "cppa/typed_behavior.hpp"
#include "cppa/typed_behavior.hpp"
#include "cppa/continue_helper.hpp"
#include "cppa/continue_helper.hpp"
#include "cppa/typed_continue_helper.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/detail/typed_actor_util.hpp"
#include "cppa/detail/response_handle_util.hpp"
#include "cppa/detail/response_handle_util.hpp"
namespace
cppa
{
namespace
cppa
{
...
@@ -46,12 +48,14 @@ namespace cppa {
...
@@ -46,12 +48,14 @@ namespace cppa {
/**
/**
* @brief This tag identifies response handles featuring a
* @brief This tag identifies response handles featuring a
* nonblocking API by providing a @p then member function.
* nonblocking API by providing a @p then member function.
* @relates response_handle
*/
*/
struct
nonblocking_response_handle_tag
{
};
struct
nonblocking_response_handle_tag
{
};
/**
/**
* @brief This tag identifies response handles featuring a
* @brief This tag identifies response handles featuring a
* blocking API by providing an @p await member function.
* blocking API by providing an @p await member function.
* @relates response_handle
*/
*/
struct
blocking_response_handle_tag
{
};
struct
blocking_response_handle_tag
{
};
...
@@ -64,12 +68,14 @@ struct blocking_response_handle_tag { };
...
@@ -64,12 +68,14 @@ struct blocking_response_handle_tag { };
* @tparam Tag Either {@link nonblocking_response_handle_tag} or
* @tparam Tag Either {@link nonblocking_response_handle_tag} or
* {@link blocking_response_handle_tag}.
* {@link blocking_response_handle_tag}.
*/
*/
template
<
class
Self
,
template
<
class
Self
,
class
Result
,
class
Tag
>
class
Result
=
any_tuple
,
class
response_handle
;
class
Tag
=
typename
Self
::
response_handle_tag
>
class
response_handle
{
// default impl for nonblocking_response_handle_tag
friend
Self
;
/******************************************************************************
* nonblocking + untyped *
******************************************************************************/
template
<
class
Self
>
class
response_handle
<
Self
,
any_tuple
,
nonblocking_response_handle_tag
>
{
public:
public:
...
@@ -79,70 +85,78 @@ class response_handle { // default impl for nonblocking_response_handle_tag
...
@@ -79,70 +85,78 @@ class response_handle { // default impl for nonblocking_response_handle_tag
response_handle
&
operator
=
(
const
response_handle
&
)
=
default
;
response_handle
&
operator
=
(
const
response_handle
&
)
=
default
;
/**
* @brief Sets @p bhvr as event-handler for the response message.
*/
inline
continue_helper
then
(
behavior
bhvr
)
{
inline
continue_helper
then
(
behavior
bhvr
)
{
return
then_impl
<
Result
>
(
std
::
move
(
bhvr
));
m_self
->
bhvr_stack
().
push_back
(
std
::
move
(
bhvr
),
m_mid
);
return
{
m_mid
,
m_self
};
}
}
/**
* @brief Sets @p mexpr as event-handler for the response message.
*/
template
<
typename
...
Cs
,
typename
...
Ts
>
template
<
typename
...
Cs
,
typename
...
Ts
>
continue_helper
then
(
const
match_expr
<
Cs
...
>&
arg
,
const
Ts
&
...
args
)
{
continue_helper
then
(
const
match_expr
<
Cs
...
>&
arg
,
const
Ts
&
...
args
)
{
return
then
_impl
<
Result
>
(
{
arg
,
args
...});
return
then
(
behavior
{
arg
,
args
...});
}
}
/**
* @brief Sets @p fun as event-handler for the response message, calls
* <tt>self->handle_sync_failure()</tt> if the response message
* is an 'EXITED' or 'VOID' message.
*/
template
<
typename
...
Fs
>
template
<
typename
...
Fs
>
typename
std
::
enable_if
<
typename
std
::
enable_if
<
util
::
all_callable
<
Fs
...
>::
value
,
util
::
all_callable
<
Fs
...
>::
value
,
continue_helper
continue_helper
>::
type
>::
type
then
(
Fs
...
fs
)
{
then
(
Fs
...
fs
)
{
return
then
_impl
<
Result
>
(
detail
::
fs2bhvr
(
m_self
,
fs
...));
return
then
(
detail
::
fs2bhvr
(
m_self
,
fs
...));
}
}
response_handle
(
const
message_id
&
mid
,
Self
*
self
)
:
m_mid
(
mid
),
m_self
(
self
)
{
}
private:
private:
template
<
typename
R
>
message_id
m_mid
;
typename
std
::
enable_if
<
std
::
is_same
<
R
,
any_tuple
>::
value
,
continue_helper
>::
type
then_impl
(
behavior
&&
bhvr
)
{
m_self
->
bhvr_stack
().
push_back
(
std
::
move
(
bhvr
),
m_mid
);
return
{
m_mid
,
m_self
};
}
template
<
typename
R
>
Self
*
m_self
;
typename
std
::
enable_if
<
util
::
is_type_list
<
R
>::
value
,
};
continue_helper
>::
type
/******************************************************************************
then_impl
(
behavior
&&
bhvr
)
{
* nonblocking + typed *
m_self
->
bhvr_stack
().
push_back
(
std
::
move
(
bhvr
),
m_mid
);
******************************************************************************/
template
<
class
Self
,
typename
...
Ts
>
class
response_handle
<
Self
,
util
::
type_list
<
Ts
...
>
,
nonblocking_response_handle_tag
>
{
public:
response_handle
()
=
delete
;
response_handle
(
const
response_handle
&
)
=
default
;
response_handle
&
operator
=
(
const
response_handle
&
)
=
default
;
template
<
typename
F
>
typed_continue_helper
<
typename
detail
::
lifted_result_type
<
typename
util
::
get_callable_trait
<
F
>::
result_type
>::
type
>
then
(
F
fun
)
{
detail
::
assert_types
<
util
::
type_list
<
Ts
...
>
,
F
>
();
m_self
->
bhvr_stack
().
push_back
(
behavior
{
on_arg_match
>>
fun
},
m_mid
);
return
{
m_mid
,
m_self
};
return
{
m_mid
,
m_self
};
}
}
response_handle
(
const
message_id
&
mid
,
Self
*
self
)
response_handle
(
const
message_id
&
mid
,
Self
*
self
)
:
m_mid
(
mid
),
m_self
(
self
)
{
}
:
m_mid
(
mid
),
m_self
(
self
)
{
}
private:
message_id
m_mid
;
message_id
m_mid
;
Self
*
m_self
;
Self
*
m_self
;
};
};
template
<
class
Self
,
typename
Result
>
/******************************************************************************
class
response_handle
<
Self
,
Result
,
blocking_response_handle_tag
>
{
* blocking + untyped *
******************************************************************************/
friend
Self
;
template
<
class
Self
>
class
response_handle
<
Self
,
any_tuple
,
blocking_response_handle_tag
>
{
public:
public:
...
@@ -152,47 +166,75 @@ class response_handle<Self, Result, blocking_response_handle_tag> {
...
@@ -152,47 +166,75 @@ class response_handle<Self, Result, blocking_response_handle_tag> {
response_handle
&
operator
=
(
const
response_handle
&
)
=
default
;
response_handle
&
operator
=
(
const
response_handle
&
)
=
default
;
/**
* @brief Blocks until the response arrives and then executes @p pfun.
*/
void
await
(
behavior
&
pfun
)
{
void
await
(
behavior
&
pfun
)
{
m_self
->
dequeue_response
(
pfun
,
m_mid
);
m_self
->
dequeue_response
(
pfun
,
m_mid
);
}
}
/**
* @copydoc await(behavior&)
*/
inline
void
await
(
behavior
&&
pfun
)
{
inline
void
await
(
behavior
&&
pfun
)
{
behavior
arg
{
std
::
move
(
pfun
)};
behavior
tmp
{
std
::
move
(
pfun
)};
await
(
arg
);
await
(
tmp
);
}
}
/**
* @brief Blocks until the response arrives and then executes
* the corresponding handler.
*/
template
<
typename
...
Cs
,
typename
...
Ts
>
template
<
typename
...
Cs
,
typename
...
Ts
>
void
await
(
const
match_expr
<
Cs
...
>&
arg
,
const
Ts
&
...
args
)
{
void
await
(
const
match_expr
<
Cs
...
>&
arg
,
const
Ts
&
...
args
)
{
await
(
match_expr_convert
(
arg
,
args
...));
await
(
match_expr_convert
(
arg
,
args
...));
}
}
/**
* @brief Blocks until the response arrives and then executes
* the corresponding handler.
* @note Calls <tt>self->handle_sync_failure()</tt> if the response
* message is an 'EXITED' or 'VOID' message.
*/
template
<
typename
...
Fs
>
template
<
typename
...
Fs
>
typename
std
::
enable_if
<
util
::
all_callable
<
Fs
...
>::
value
>::
type
typename
std
::
enable_if
<
util
::
all_callable
<
Fs
...
>::
value
>::
type
await
(
Fs
...
fs
)
{
await
(
Fs
...
fs
)
{
await
(
detail
::
fs2bhvr
(
m_self
,
fs
...));
await
(
detail
::
fs2bhvr
(
m_self
,
fs
...));
}
}
response_handle
(
const
message_id
&
mid
,
Self
*
self
)
:
m_mid
(
mid
),
m_self
(
self
)
{
}
private:
private:
message_id
m_mid
;
Self
*
m_self
;
};
/******************************************************************************
* blocking + typed *
******************************************************************************/
template
<
class
Self
,
typename
...
Ts
>
class
response_handle
<
Self
,
util
::
type_list
<
Ts
...
>
,
blocking_response_handle_tag
>
{
public:
typedef
util
::
type_list
<
Ts
...
>
result_types
;
response_handle
()
=
delete
;
response_handle
(
const
response_handle
&
)
=
default
;
response_handle
&
operator
=
(
const
response_handle
&
)
=
default
;
template
<
typename
F
>
void
await
(
F
fun
)
{
typedef
typename
util
::
tl_map
<
typename
util
::
get_callable_trait
<
F
>::
arg_types
,
util
::
rm_const_and_ref
>::
type
arg_types
;
static
constexpr
size_t
fun_args
=
util
::
tl_size
<
arg_types
>::
value
;
static_assert
(
fun_args
<=
util
::
tl_size
<
result_types
>::
value
,
"functor takes too much arguments"
);
typedef
typename
util
::
tl_right
<
result_types
,
fun_args
>::
type
recv_types
;
static_assert
(
std
::
is_same
<
arg_types
,
recv_types
>::
value
,
"wrong functor signature"
);
behavior
tmp
=
detail
::
fs2bhvr
(
m_self
,
fun
);
m_self
->
dequeue_response
(
tmp
,
m_mid
);
}
response_handle
(
const
message_id
&
mid
,
Self
*
self
)
response_handle
(
const
message_id
&
mid
,
Self
*
self
)
:
m_mid
(
mid
),
m_self
(
self
)
{
}
:
m_mid
(
mid
),
m_self
(
self
)
{
}
private:
message_id
m_mid
;
message_id
m_mid
;
Self
*
m_self
;
Self
*
m_self
;
...
...
cppa/spawn.hpp
View file @
3ce764a9
...
@@ -70,7 +70,7 @@ intrusive_ptr<Impl> spawn_impl(BeforeLaunch before_launch_fun, Ts&&... args) {
...
@@ -70,7 +70,7 @@ intrusive_ptr<Impl> spawn_impl(BeforeLaunch before_launch_fun, Ts&&... args) {
&&
!
has_detach_flag
(
Opts
)
&&
!
has_detach_flag
(
Opts
)
&&
util
::
fiber
::
is_disabled_feature
())
{
&&
util
::
fiber
::
is_disabled_feature
())
{
return
spawn_impl
<
Impl
,
Opts
+
detached
>
(
before_launch_fun
,
return
spawn_impl
<
Impl
,
Opts
+
detached
>
(
before_launch_fun
,
std
::
forward
<
Ts
>
(
args
)...);
std
::
forward
<
Ts
>
(
args
)...);
}
}
/*
/*
using scheduling_policy = typename std::conditional<
using scheduling_policy = typename std::conditional<
...
@@ -224,7 +224,7 @@ class functor_based_typed_actor : public typed_event_based_actor<Sigs...> {
...
@@ -224,7 +224,7 @@ class functor_based_typed_actor : public typed_event_based_actor<Sigs...> {
public:
public:
typedef
functor_based_typed_actor
*
pointer
;
typedef
typed_event_based_actor
<
Sigs
...
>
*
pointer
;
typedef
typename
super
::
behavior_type
behavior_type
;
typedef
typename
super
::
behavior_type
behavior_type
;
typedef
std
::
function
<
typed_behavior
<
Sigs
...
>
()
>
no_arg_fun
;
typedef
std
::
function
<
typed_behavior
<
Sigs
...
>
()
>
no_arg_fun
;
...
@@ -264,6 +264,14 @@ struct actor_handle_from_typed_behavior<typed_behavior<Signatures...>> {
...
@@ -264,6 +264,14 @@ struct actor_handle_from_typed_behavior<typed_behavior<Signatures...>> {
typedef
typed_actor
<
Signatures
...
>
type
;
typedef
typed_actor
<
Signatures
...
>
type
;
};
};
template
<
typename
SignatureList
>
struct
actor_handle_from_signature_list
;
template
<
typename
...
Signatures
>
struct
actor_handle_from_signature_list
<
util
::
type_list
<
Signatures
...
>>
{
typedef
typed_actor
<
Signatures
...
>
type
;
};
}
// namespace detail
}
// namespace detail
template
<
spawn_options
Options
=
no_spawn_options
,
typename
F
>
template
<
spawn_options
Options
=
no_spawn_options
,
typename
F
>
...
@@ -280,6 +288,17 @@ spawn_typed(F fun) {
...
@@ -280,6 +288,17 @@ spawn_typed(F fun) {
std
::
move
(
fun
));
std
::
move
(
fun
));
}
}
template
<
class
Impl
,
spawn_options
Options
=
no_spawn_options
,
typename
...
Ts
>
typename
detail
::
actor_handle_from_signature_list
<
typename
Impl
::
signatures
>::
type
spawn_typed
(
Ts
&&
...
args
)
{
return
detail
::
spawn_fwd_args
<
Impl
,
Options
>
(
[
&
](
Impl
*
)
{
},
std
::
forward
<
Ts
>
(
args
)...);
}
/*
/*
template<class Impl, spawn_options Opts = no_spawn_options, typename... Ts>
template<class Impl, spawn_options Opts = no_spawn_options, typename... Ts>
typename Impl::typed_pointer_type spawn_typed(Ts&&... args) {
typename Impl::typed_pointer_type spawn_typed(Ts&&... args) {
...
...
cppa/sync_sender.hpp
0 → 100644
View file @
3ce764a9
This diff is collapsed.
Click to expand it.
cppa/typed_actor.hpp
View file @
3ce764a9
...
@@ -35,6 +35,7 @@
...
@@ -35,6 +35,7 @@
#include "cppa/replies_to.hpp"
#include "cppa/replies_to.hpp"
#include "cppa/intrusive_ptr.hpp"
#include "cppa/intrusive_ptr.hpp"
#include "cppa/abstract_actor.hpp"
#include "cppa/abstract_actor.hpp"
#include "cppa/typed_behavior.hpp"
namespace
cppa
{
namespace
cppa
{
...
@@ -43,6 +44,12 @@ class local_actor;
...
@@ -43,6 +44,12 @@ class local_actor;
struct
invalid_actor_addr_t
;
struct
invalid_actor_addr_t
;
template
<
typename
...
Signatures
>
class
typed_event_based_actor
;
/**
* @brief Identifies a strongly typed actor.
*/
template
<
typename
...
Signatures
>
template
<
typename
...
Signatures
>
class
typed_actor
:
util
::
comparable
<
typed_actor
<
Signatures
...
>>
class
typed_actor
:
util
::
comparable
<
typed_actor
<
Signatures
...
>>
,
util
::
comparable
<
typed_actor
<
Signatures
...
>
,
actor_addr
>
,
util
::
comparable
<
typed_actor
<
Signatures
...
>
,
actor_addr
>
...
@@ -52,6 +59,22 @@ class typed_actor : util::comparable<typed_actor<Signatures...>>
...
@@ -52,6 +59,22 @@ class typed_actor : util::comparable<typed_actor<Signatures...>>
public:
public:
/**
* @brief Identifies the behavior type actors of this kind use
* for their behavior stack.
*/
typedef
typed_behavior
<
Signatures
...
>
behavior_type
;
/**
* @brief Identifies pointers to instances of this kind of actor.
*/
typedef
typed_event_based_actor
<
Signatures
...
>*
pointer
;
/**
* @brief Identifies the base class for this kind of actor.
*/
typedef
typed_event_based_actor
<
Signatures
...
>
impl
;
typedef
util
::
type_list
<
Signatures
...
>
signatures
;
typedef
util
::
type_list
<
Signatures
...
>
signatures
;
typed_actor
()
=
default
;
typed_actor
()
=
default
;
...
@@ -71,8 +94,8 @@ class typed_actor : util::comparable<typed_actor<Signatures...>>
...
@@ -71,8 +94,8 @@ class typed_actor : util::comparable<typed_actor<Signatures...>>
return
*
this
;
return
*
this
;
}
}
template
<
template
<
typename
...
>
class
Impl
,
typename
...
OtherSignatures
>
template
<
class
Impl
>
typed_actor
(
intrusive_ptr
<
Impl
<
OtherSignatures
...
>
>
other
)
{
typed_actor
(
intrusive_ptr
<
Impl
>
other
)
{
set
(
other
);
set
(
other
);
}
}
...
@@ -105,9 +128,9 @@ class typed_actor : util::comparable<typed_actor<Signatures...>>
...
@@ -105,9 +128,9 @@ class typed_actor : util::comparable<typed_actor<Signatures...>>
m_ptr
=
other
.
m_ptr
;
m_ptr
=
other
.
m_ptr
;
}
}
template
<
template
<
typename
...
>
class
Impl
,
typename
...
OtherSignatures
>
template
<
class
Impl
>
inline
void
set
(
intrusive_ptr
<
Impl
<
OtherSignatures
...
>
>&
other
)
{
inline
void
set
(
intrusive_ptr
<
Impl
>&
other
)
{
check_signatures
<
signatures
,
util
::
type_list
<
OtherSignatures
...
>
>
();
check_signatures
<
signatures
,
typename
Impl
::
signatures
>
();
m_ptr
=
std
::
move
(
other
);
m_ptr
=
std
::
move
(
other
);
}
}
...
...
cppa/typed_behavior.hpp
View file @
3ce764a9
...
@@ -38,20 +38,20 @@
...
@@ -38,20 +38,20 @@
namespace
cppa
{
namespace
cppa
{
template
<
class
,
typename
...>
class
typed_behavior_stack_based
;
template
<
typename
...
Signatures
>
template
<
typename
...
Signatures
>
class
typed_actor
;
class
typed_actor
;
template
<
class
Base
,
class
Subtype
,
class
BehaviorType
>
class
behavior_stack_based_impl
;
template
<
typename
...
Signatures
>
template
<
typename
...
Signatures
>
class
typed_behavior
{
class
typed_behavior
{
template
<
typename
...
OtherSignatures
>
template
<
typename
...
OtherSignatures
>
friend
class
typed_actor
;
friend
class
typed_actor
;
template
<
class
,
typename
...
>
template
<
class
Base
,
class
Subtype
,
class
BehaviorType
>
friend
class
typed_behavior_stack_based
;
friend
class
behavior_stack_based_impl
;
typed_behavior
()
=
delete
;
typed_behavior
()
=
delete
;
...
...
cppa/typed_behavior_stack_based.hpp
deleted
100644 → 0
View file @
5e5ccb08
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011-2013 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef CPPA_TYPED_BEHAVIOR_STACK_BASED_HPP
#define CPPA_TYPED_BEHAVIOR_STACK_BASED_HPP
#include <utility>
#include "cppa/single_timeout.hpp"
#include "cppa/behavior_policy.hpp"
#include "cppa/typed_event_based_actor.hpp"
#include "cppa/util/type_traits.hpp"
#include "cppa/detail/behavior_stack.hpp"
namespace
cppa
{
/**
* @brief Mixin for actors using a typed stack-based message processing.
* @note This mixin implicitly includes {@link single_timeout}.
* @note Subtype must provide a typedef for @p behavior_type.
*/
template
<
class
Base
,
typename
...
Signatures
>
class
typed_behavior_stack_based
:
public
extend
<
Base
>::
template
with
<
single_timeout
>
{
public:
typedef
typed_behavior
<
Signatures
...
>
behavior_type
;
/**
* @brief Sets the actor's behavior and discards the previous behavior
* unless {@link keep_behavior} is given as first argument.
*/
void
become
(
behavior_type
bhvr
)
{
do_become
(
std
::
move
(
bhvr
),
true
);
}
template
<
bool
Discard
>
void
become
(
behavior_policy
<
Discard
>
,
behavior_type
bhvr
)
{
do_become
(
std
::
move
(
bhvr
),
Discard
);
}
template
<
typename
T
,
typename
...
Ts
>
inline
typename
std
::
enable_if
<
!
is_behavior_policy
<
typename
util
::
rm_const_and_ref
<
T
>::
type
>::
value
,
void
>::
type
become
(
T
&&
arg
,
Ts
&&
...
args
)
{
do_become
(
behavior_type
{
std
::
forward
<
T
>
(
arg
),
std
::
forward
<
Ts
>
(
args
)...},
true
);
}
template
<
bool
Discard
,
typename
...
Ts
>
void
become
(
behavior_policy
<
Discard
>
,
Ts
&&
...
args
)
{
do_become
(
behavior_type
{
std
::
forward
<
Ts
>
(
args
)...},
Discard
);
}
inline
void
unbecome
()
{
m_bhvr_stack
.
pop_async_back
();
}
inline
bool
has_behavior
()
const
{
return
m_bhvr_stack
.
empty
()
==
false
;
}
inline
behavior
&
get_behavior
()
{
CPPA_REQUIRE
(
m_bhvr_stack
.
empty
()
==
false
);
return
m_bhvr_stack
.
back
();
}
inline
detail
::
behavior_stack
&
bhvr_stack
()
{
return
m_bhvr_stack
;
}
optional
<
behavior
&>
sync_handler
(
message_id
msg_id
)
override
{
return
m_bhvr_stack
.
sync_handler
(
msg_id
);
}
inline
void
remove_handler
(
message_id
mid
)
{
m_bhvr_stack
.
erase
(
mid
);
}
private:
void
do_become
(
behavior_type
bhvr
,
bool
discard_old
)
{
if
(
discard_old
)
this
->
m_bhvr_stack
.
pop_async_back
();
this
->
reset_timeout
();
if
(
bhvr
.
timeout
().
valid
())
{
this
->
request_timeout
(
bhvr
.
timeout
());
}
this
->
m_bhvr_stack
.
push_back
(
std
::
move
(
bhvr
.
unbox
()));
}
// allows actors to keep previous behaviors and enables unbecome()
detail
::
behavior_stack
m_bhvr_stack
;
};
}
// namespace cppa
#endif // CPPA_TYPED_BEHAVIOR_STACK_BASED_HPP
cppa/typed_
actor_base
.hpp
→
cppa/typed_
continue_helper
.hpp
View file @
3ce764a9
...
@@ -28,71 +28,44 @@
...
@@ -28,71 +28,44 @@
\******************************************************************************/
\******************************************************************************/
#ifndef CPPA_TYPED_
ACTO
R_HPP
#ifndef CPPA_TYPED_
CONTINUE_HELPE
R_HPP
#define CPPA_TYPED_
ACTO
R_HPP
#define CPPA_TYPED_
CONTINUE_HELPE
R_HPP
#include "cppa/replies_to.hpp"
#include "cppa/continue_helper.hpp"
#include "cppa/typed_behavior.hpp"
#include "cppa/event_based_actor.hpp"
#include "cppa/
detail/typed_actor_util
.hpp"
#include "cppa/
util/type_traits
.hpp"
namespace
cppa
{
namespace
cppa
{
template
<
typename
...
Signatures
>
template
<
typename
OutputList
>
class
typed_actor_ptr
;
class
typed_continue_helper
{
template
<
typename
...
Signatures
>
class
typed_actor
:
public
event_based_actor
{
public:
public:
using
signatures
=
util
::
type_list
<
Signatures
...
>
;
typedef
int
message_id_wrapper_tag
;
using
behavior_type
=
typed_behavior
<
Signatures
...
>
;
using
typed_pointer_type
=
typed_actor_ptr
<
Signatures
...
>
;
protected:
virtual
behavior_type
make_behavior
()
=
0
;
typed_continue_helper
(
message_id
mid
,
local_actor
*
self
)
:
m_ch
(
mid
,
self
)
{
}
void
init
()
final
{
template
<
typename
F
>
auto
bhvr
=
make_behavior
();
typed_continue_helper
<
typename
util
::
get_callable_trait
<
F
>::
result_type
>
m_bhvr_stack
.
push_back
(
std
::
move
(
bhvr
.
unbox
()));
continue_with
(
F
fun
)
{
detail
::
assert_types
<
OutputList
,
F
>
();
m_ch
.
continue_with
(
std
::
move
(
fun
));
return
{
m_ch
};
}
}
void
do_become
(
behavior
&&
,
bool
)
final
{
inline
message_id
get_message_id
()
const
{
CPPA_LOG_ERROR
(
"typed actors are not allowed to call become()"
);
return
m_ch
.
get_message_id
();
quit
(
exit_reason
::
unallowed_function_call
);
}
}
};
typed_continue_helper
(
continue_helper
ch
)
:
m_ch
(
std
::
move
(
ch
))
{
}
}
// namespace cppa
namespace
cppa
{
namespace
detail
{
template
<
typename
...
Signatures
>
class
default_typed_actor
:
public
typed_actor
<
Signatures
...
>
{
public:
template
<
typename
...
Cases
>
default_typed_actor
(
match_expr
<
Cases
...
>
expr
)
:
m_bhvr
(
std
::
move
(
expr
))
{
}
protected:
typed_behavior
<
Signatures
...
>
make_behavior
()
override
{
return
m_bhvr
;
}
private:
private:
typed_behavior
<
Signatures
...
>
m_bhvr
;
continue_helper
m_ch
;
};
};
}
}
// namespace cppa::detail
}
// namespace cppa
#endif // CPPA_TYPED_
ACTO
R_HPP
#endif // CPPA_TYPED_
CONTINUE_HELPE
R_HPP
cppa/typed_event_based_actor.hpp
View file @
3ce764a9
...
@@ -33,17 +33,23 @@
...
@@ -33,17 +33,23 @@
#include "cppa/replies_to.hpp"
#include "cppa/replies_to.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/sync_sender.hpp"
#include "cppa/mailbox_based.hpp"
#include "cppa/mailbox_based.hpp"
#include "cppa/typed_behavior.hpp"
#include "cppa/typed_behavior.hpp"
#include "cppa/
typed_
behavior_stack_based.hpp"
#include "cppa/behavior_stack_based.hpp"
namespace
cppa
{
namespace
cppa
{
template
<
typename
...
Signatures
>
template
<
typename
...
Signatures
>
class
typed_event_based_actor
:
public
typed_behavior_stack_based
<
class
typed_event_based_actor
extend
<
local_actor
>::
template
:
public
extend
<
local_actor
,
typed_event_based_actor
<
Signatures
...
>>::
template
with
<
mailbox_based
>,
with
<
mailbox_based
,
Signatures
...
>
{
behavior_stack_based
<
typed_behavior
<
Signatures
...>
>::
template
impl
,
sync_sender
<
nonblocking_response_handle_tag
>
::
template
impl
>
{
public:
public:
...
...
unit_testing/test_typed_spawn.cpp
View file @
3ce764a9
...
@@ -37,11 +37,13 @@ using namespace cppa;
...
@@ -37,11 +37,13 @@ using namespace cppa;
struct
my_request
{
int
a
;
int
b
;
};
struct
my_request
{
int
a
;
int
b
;
};
typedef
typed_actor
<
replies_to
<
my_request
>::
with
<
bool
>>
server_type
;
bool
operator
==
(
const
my_request
&
lhs
,
const
my_request
&
rhs
)
{
bool
operator
==
(
const
my_request
&
lhs
,
const
my_request
&
rhs
)
{
return
lhs
.
a
==
rhs
.
a
&&
lhs
.
b
==
rhs
.
b
;
return
lhs
.
a
==
rhs
.
a
&&
lhs
.
b
==
rhs
.
b
;
}
}
typed_behavior
<
replies_to
<
my_request
>::
with
<
bool
>>
typed_server
()
{
server_type
::
behavior_type
typed_server1
()
{
return
{
return
{
on_arg_match
>>
[](
const
my_request
&
req
)
{
on_arg_match
>>
[](
const
my_request
&
req
)
{
return
req
.
a
==
req
.
b
;
return
req
.
a
==
req
.
b
;
...
@@ -49,33 +51,41 @@ typed_behavior<replies_to<my_request>::with<bool>> typed_server() {
...
@@ -49,33 +51,41 @@ typed_behavior<replies_to<my_request>::with<bool>> typed_server() {
};
};
}
}
/*
server_type
::
behavior_type
typed_server2
(
server_type
::
pointer
)
{
typed_actor_ptr<replies_to<my_request>::with<bool>>
return
typed_server1
();
spawn_typed_server() {
return spawn_typed(
on_arg_match >> [](const my_request& req) {
return req.a == req.b;
}
);
}
}
class typed_
testee : public typed_actor<replies_to<my_request>::with<bool>>
{
class
typed_
server3
:
public
server_type
::
impl
{
protected:
public:
typed_server3
(
const
string
&
line
,
actor
buddy
)
{
send
(
buddy
,
line
);
}
behavior_type
make_behavior
()
override
{
behavior_type
make_behavior
()
override
{
return (
return
typed_server2
(
this
);
on_arg_match >> [](const my_request& req) {
return req.a == req.b;
}
);
}
}
};
};
*/
void
test_typed_spawn
()
{
void
client
(
event_based_actor
*
self
,
actor
parent
,
server_type
serv
)
{
auto
ts
=
spawn_typed
(
typed_server
);
self
->
sync_send
(
serv
,
my_request
{
0
,
0
}).
then
(
[](
bool
value
)
{
CPPA_CHECK_EQUAL
(
value
,
true
);
}
)
.
continue_with
([
=
]
{
self
->
sync_send
(
serv
,
my_request
{
10
,
20
}).
then
(
[
=
](
bool
value
)
{
CPPA_CHECK_EQUAL
(
value
,
false
);
self
->
send
(
parent
,
atom
(
"passed"
));
}
);
});
}
void
test_typed_spawn
(
server_type
ts
)
{
scoped_actor
self
;
scoped_actor
self
;
self
->
send
(
ts
,
my_request
{
1
,
2
});
self
->
send
(
ts
,
my_request
{
1
,
2
});
self
->
receive
(
self
->
receive
(
...
@@ -89,13 +99,47 @@ void test_typed_spawn() {
...
@@ -89,13 +99,47 @@ void test_typed_spawn() {
CPPA_CHECK_EQUAL
(
value
,
true
);
CPPA_CHECK_EQUAL
(
value
,
true
);
}
}
);
);
self
->
sync_send
(
ts
,
my_request
{
10
,
20
}).
await
(
[](
bool
value
)
{
CPPA_CHECK_EQUAL
(
value
,
false
);
}
);
self
->
sync_send
(
ts
,
my_request
{
0
,
0
}).
await
(
[](
bool
value
)
{
CPPA_CHECK_EQUAL
(
value
,
true
);
}
);
self
->
spawn
<
monitored
>
(
client
,
self
,
ts
);
self
->
receive
(
on
(
atom
(
"passed"
))
>>
CPPA_CHECKPOINT_CB
()
);
self
->
receive
(
on_arg_match
>>
[](
const
down_msg
&
dmsg
)
{
CPPA_CHECK_EQUAL
(
dmsg
.
reason
,
exit_reason
::
normal
);
}
);
self
->
send_exit
(
ts
,
exit_reason
::
user_shutdown
);
self
->
send_exit
(
ts
,
exit_reason
::
user_shutdown
);
}
}
int
main
()
{
int
main
()
{
CPPA_TEST
(
test_typed_spawn
);
CPPA_TEST
(
test_typed_spawn
);
announce
<
my_request
>
(
&
my_request
::
a
,
&
my_request
::
b
);
announce
<
my_request
>
(
&
my_request
::
a
,
&
my_request
::
b
);
test_typed_spawn
();
test_typed_spawn
(
spawn_typed
(
typed_server1
));
CPPA_CHECKPOINT
();
await_all_actors_done
();
CPPA_CHECKPOINT
();
test_typed_spawn
(
spawn_typed
(
typed_server2
));
CPPA_CHECKPOINT
();
await_all_actors_done
();
CPPA_CHECKPOINT
();
{
scoped_actor
self
;
test_typed_spawn
(
spawn_typed
<
typed_server3
>
(
"hi there"
,
self
));
self
->
receive
(
on
(
"hi there"
)
>>
CPPA_CHECKPOINT_CB
()
);
}
CPPA_CHECKPOINT
();
await_all_actors_done
();
await_all_actors_done
();
shutdown
();
shutdown
();
/*
/*
...
...
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