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
4d42b255
Commit
4d42b255
authored
Jul 07, 2015
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement stateful actors, relates #293
parent
f4516192
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
185 additions
and
8 deletions
+185
-8
libcaf_core/caf/experimental/stateful_actor.hpp
libcaf_core/caf/experimental/stateful_actor.hpp
+43
-3
libcaf_core/caf/spawn.hpp
libcaf_core/caf/spawn.hpp
+11
-5
libcaf_core/caf/typed_actor.hpp
libcaf_core/caf/typed_actor.hpp
+10
-0
libcaf_core/test/stateful_actor.cpp
libcaf_core/test/stateful_actor.cpp
+121
-0
No files found.
libcaf_core/caf/experimental/stateful_actor.hpp
View file @
4d42b255
...
...
@@ -20,15 +20,55 @@
#ifndef CAF_EXPERIMENTAL_STATEFUL_ACTOR_HPP
#define CAF_EXPERIMENTAL_STATEFUL_ACTOR_HPP
#include "caf/event_based_actor.hpp"
#include <new>
#include <type_traits>
#include "caf/fwd.hpp"
namespace
caf
{
namespace
experimental
{
template
<
class
State
>
class
stateful_actor
:
public
event_based_actor
{
template
<
class
State
,
class
Base
=
event_based_actor
>
class
stateful_actor
:
public
Base
{
public:
stateful_actor
()
{
// nop
}
~
stateful_actor
()
{
// nop
}
void
initialize
()
override
{
cr_state
(
this
);
Base
::
initialize
();
}
void
on_exit
()
override
final
{
state_
.
~
State
();
}
State
&
state
()
{
return
state_
;
}
private:
template
<
class
T
>
typename
std
::
enable_if
<
std
::
is_constructible
<
State
,
T
>::
value
>::
type
cr_state
(
T
arg
)
{
new
(
&
state_
)
State
(
arg
);
}
template
<
class
T
>
typename
std
::
enable_if
<!
std
::
is_constructible
<
State
,
T
>::
value
>::
type
cr_state
(
T
)
{
new
(
&
state_
)
State
();
}
union
{
State
state_
;
};
};
}
// namespace experimental
}
// namespace caf
#endif // CAF_EXPERIMENTAL_STATEFUL_ACTOR_HPP
libcaf_core/caf/spawn.hpp
View file @
4d42b255
...
...
@@ -199,17 +199,23 @@ actor spawn_in_group(const group& grp, Ts&&... xs) {
/// Infers the appropriate base class for a functor-based typed actor
/// from the result and the first argument of the functor.
template
<
class
Result
,
class
FirstArg
>
template
<
class
Result
,
class
FirstArg
,
bool
FirstArgPtr
=
std
::
is_pointer
<
FirstArg
>
::
value
&&
std
::
is_base_of
<
local_actor
,
typename
std
::
remove_pointer
<
FirstArg
>::
type
>::
value
>
struct
infer_typed_actor_base
;
template
<
class
...
Sigs
,
class
FirstArg
>
struct
infer_typed_actor_base
<
typed_behavior
<
Sigs
...
>
,
FirstArg
>
{
struct
infer_typed_actor_base
<
typed_behavior
<
Sigs
...
>
,
FirstArg
,
false
>
{
using
type
=
typed_event_based_actor
<
Sigs
...
>
;
};
template
<
class
...
Sigs
>
struct
infer_typed_actor_base
<
void
,
typed_event_based_actor
<
Sigs
...
>*
>
{
using
type
=
typed_event_based_actor
<
Sigs
...
>
;
template
<
class
Result
,
class
T
>
struct
infer_typed_actor_base
<
Result
,
T
*
,
true
>
{
using
type
=
T
;
};
/// Returns a new typed actor of type `C` using `xs...` as
...
...
libcaf_core/caf/typed_actor.hpp
View file @
4d42b255
...
...
@@ -29,6 +29,8 @@
#include "caf/typed_behavior.hpp"
#include "caf/typed_response_promise.hpp"
#include "caf/experimental/stateful_actor.hpp"
namespace
caf
{
class
actor_addr
;
...
...
@@ -92,6 +94,14 @@ class typed_actor : detail::comparable<typed_actor<Sigs...>>,
/// Stores the template parameter pack.
using
signatures
=
detail
::
type_list
<
Sigs
...
>
;
/// Identifies the base class for this kind of actor with actor.
template
<
class
State
>
using
stateful_base
=
experimental
::
stateful_actor
<
State
,
base
>
;
/// Identifies the base class for this kind of actor with actor.
template
<
class
State
>
using
stateful_pointer
=
experimental
::
stateful_actor
<
State
,
base
>*
;
typed_actor
()
=
default
;
typed_actor
(
typed_actor
&&
)
=
default
;
typed_actor
(
const
typed_actor
&
)
=
default
;
...
...
libcaf_core/test/stateful_actor.cpp
0 → 100644
View file @
4d42b255
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright (C) 2011 - 2015 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/config.hpp"
#define CAF_SUITE stateful_actor
#include "caf/test/unit_test.hpp"
#include "caf/all.hpp"
#include "caf/experimental/stateful_actor.hpp"
using
namespace
std
;
using
namespace
caf
;
using
namespace
caf
::
experimental
;
namespace
{
using
typed_adder_actor
=
typed_actor
<
reacts_to
<
add_atom
,
int
>
,
replies_to
<
get_atom
>::
with
<
int
>>
;
struct
counter
{
int
value
=
0
;
local_actor
*
self_
;
};
behavior
adder
(
stateful_actor
<
counter
>*
self
)
{
return
{
[
=
](
add_atom
,
int
x
)
{
self
->
state
().
value
+=
x
;
},
[
=
](
get_atom
)
{
return
self
->
state
().
value
;
}
};
}
class
adder_class
:
public
stateful_actor
<
counter
>
{
public:
behavior
make_behavior
()
override
{
return
adder
(
this
);
}
};
typed_adder_actor
::
behavior_type
typed_adder
(
typed_adder_actor
::
stateful_pointer
<
counter
>
self
)
{
return
{
[
=
](
add_atom
,
int
x
)
{
self
->
state
().
value
+=
x
;
},
[
=
](
get_atom
)
{
return
self
->
state
().
value
;
}
};
}
class
typed_adder_class
:
public
typed_adder_actor
::
stateful_base
<
counter
>
{
public:
behavior_type
make_behavior
()
override
{
return
typed_adder
(
this
);
}
};
struct
fixture
{
~
fixture
()
{
await_all_actors_done
();
shutdown
();
}
};
template
<
class
ActorUnderTest
>
void
test_adder
(
ActorUnderTest
aut
)
{
scoped_actor
self
;
self
->
send
(
aut
,
add_atom
::
value
,
7
);
self
->
send
(
aut
,
add_atom
::
value
,
4
);
self
->
send
(
aut
,
add_atom
::
value
,
9
);
self
->
sync_send
(
aut
,
get_atom
::
value
).
await
(
[](
int
x
)
{
CAF_CHECK_EQUAL
(
x
,
20
);
}
);
anon_send_exit
(
aut
,
exit_reason
::
kill
);
}
}
// namespace <anonymous>
CAF_TEST_FIXTURE_SCOPE
(
dynamic_stateful_actor_tests
,
fixture
)
CAF_TEST
(
dynamic_stateful_actor
)
{
test_adder
(
spawn
(
adder
));
}
CAF_TEST
(
typed_stateful_actor
)
{
test_adder
(
spawn_typed
(
typed_adder
));
}
CAF_TEST
(
dynamic_stateful_actor_class
)
{
test_adder
(
spawn
<
adder_class
>
());
}
CAF_TEST
(
typed_stateful_actor_class
)
{
test_adder
(
spawn_typed
<
typed_adder_class
>
());
}
CAF_TEST_FIXTURE_SCOPE_END
()
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