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
eb29971e
Commit
eb29971e
authored
Aug 07, 2014
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' of github.com:actor-framework/actor-framework into develop
parents
6a8fd3e5
5c0525b7
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
816 additions
and
437 deletions
+816
-437
CMakeLists.txt
CMakeLists.txt
+18
-6
FindOPENCL.cmake
FindOPENCL.cmake
+56
-0
examples/CMakeLists.txt
examples/CMakeLists.txt
+62
-10
examples/qtsupport/chatwidget.cpp
examples/qtsupport/chatwidget.cpp
+131
-0
examples/qtsupport/chatwidget.hpp
examples/qtsupport/chatwidget.hpp
+56
-0
examples/qtsupport/chatwindow.ui
examples/qtsupport/chatwindow.ui
+166
-0
examples/qtsupport/qt_group_chat.cpp
examples/qtsupport/qt_group_chat.cpp
+109
-0
libcaf_core/caf/detail/default_uniform_type_info.hpp
libcaf_core/caf/detail/default_uniform_type_info.hpp
+82
-76
libcaf_core/caf/detail/type_traits.hpp
libcaf_core/caf/detail/type_traits.hpp
+10
-0
libcaf_core/caf/mixin/actor_widget.hpp
libcaf_core/caf/mixin/actor_widget.hpp
+102
-0
libcaf_core/caf/on.hpp
libcaf_core/caf/on.hpp
+6
-11
libcaf_io/caf/io/hook.hpp
libcaf_io/caf/io/hook.hpp
+2
-2
libcaf_io/caf/io/publish_impl.hpp
libcaf_io/caf/io/publish_impl.hpp
+6
-6
libcaf_io/src/basp_broker.cpp
libcaf_io/src/basp_broker.cpp
+8
-2
libcaf_io/src/hook.cpp
libcaf_io/src/hook.cpp
+2
-2
unit_testing/test_opencl.cpp
unit_testing/test_opencl.cpp
+0
-322
No files found.
CMakeLists.txt
View file @
eb29971e
...
@@ -108,7 +108,7 @@ else()
...
@@ -108,7 +108,7 @@ else()
message
(
STATUS
"NOTE: Automatically added -stdlib=libc++ flag, "
message
(
STATUS
"NOTE: Automatically added -stdlib=libc++ flag, "
"you can override this by defining CMAKE_CXX_FLAGS "
"you can override this by defining CMAKE_CXX_FLAGS "
"(see 'configure --help')"
)
"(see 'configure --help')"
)
set
(
CMAKE_CXX_FLAGS
"-std=c++11 -stdlib=libc++"
)
set
(
CMAKE_CXX_FLAGS
"-std=c++11 -stdlib=libc++
-fPIC
"
)
if
(
MORE_CLANG_WARNINGS
)
if
(
MORE_CLANG_WARNINGS
)
set
(
CMAKE_CXX_FLAGS
"-pedantic -Weverything -Wno-c++98-compat "
set
(
CMAKE_CXX_FLAGS
"-pedantic -Weverything -Wno-c++98-compat "
"-Wno-padded -Wno-documentation-unknown-command "
"-Wno-padded -Wno-documentation-unknown-command "
...
@@ -118,7 +118,7 @@ else()
...
@@ -118,7 +118,7 @@ else()
"-Wno-unused-const-variable"
)
"-Wno-unused-const-variable"
)
endif
()
endif
()
else
()
else
()
set
(
CMAKE_CXX_FLAGS
"-std=c++11 -Wextra -Wall -pedantic"
)
set
(
CMAKE_CXX_FLAGS
"-std=c++11 -Wextra -Wall -pedantic
-fPIC
"
)
endif
()
endif
()
set
(
CMAKE_CXX_FLAGS_DEBUG
"-O0 -g"
)
set
(
CMAKE_CXX_FLAGS_DEBUG
"-O0 -g"
)
set
(
CMAKE_CXX_FLAGS_MINSIZEREL
"-Os"
)
set
(
CMAKE_CXX_FLAGS_MINSIZEREL
"-Os"
)
...
@@ -204,9 +204,9 @@ set(LIBCAF_INCLUDE_DIRS
...
@@ -204,9 +204,9 @@ set(LIBCAF_INCLUDE_DIRS
${
CMAKE_SOURCE_DIR
}
/libcaf_core
${
CMAKE_SOURCE_DIR
}
/libcaf_core
${
CMAKE_SOURCE_DIR
}
/libcaf_io
)
${
CMAKE_SOURCE_DIR
}
/libcaf_io
)
# path to caf opencl headers
# path to caf opencl headers
if
(
EXISTS
${
CMAKE_SOURCE_D
O
R
}
/libcaf_opencl/caf
)
if
(
EXISTS
${
CMAKE_SOURCE_D
I
R
}
/libcaf_opencl/caf
)
set
(
LIBCAF_INCLUDE_DIRS
${
LIBCAF_INCLUDE_DIRS
}
set
(
LIBCAF_INCLUDE_DIRS
${
CMAKE_SOURCE_DIR
}
/libcaf_opencl
)
${
CMAKE_SOURCE_DIR
}
/libcaf_opencl/
${
LIBCAF_INCLUDE_DIRS
}
)
endif
()
endif
()
# path to probe-event headers (if submodule is loaded)
# path to probe-event headers (if submodule is loaded)
...
@@ -239,7 +239,9 @@ set(LIBCAF_IO_LIBRARY libcaf_io)
...
@@ -239,7 +239,9 @@ set(LIBCAF_IO_LIBRARY libcaf_io)
# set opencl lib for sub directories if not told otherwise
# set opencl lib for sub directories if not told otherwise
if
(
NOT CAF_NO_OPENCL AND EXISTS
"
${
CMAKE_SOURCE_DIR
}
/libcaf_opencl/caf"
)
if
(
NOT CAF_NO_OPENCL AND EXISTS
"
${
CMAKE_SOURCE_DIR
}
/libcaf_opencl/caf"
)
message
(
STATUS
"Enter subdirectory libcaf_opencl"
)
message
(
STATUS
"Enter subdirectory libcaf_opencl"
)
find_package
(
OPENCL REQUIRED
)
add_subdirectory
(
libcaf_opencl
)
add_subdirectory
(
libcaf_opencl
)
set
(
LIBCAF_OPENCL_LIBRARY libcaf_opencl
)
endif
()
endif
()
# tell CMake caf_io depends on caf_core
# tell CMake caf_io depends on caf_core
if
(
CAF_BUILD_STATIC_ONLY OR CAF_BUILD_STATIC
)
if
(
CAF_BUILD_STATIC_ONLY OR CAF_BUILD_STATIC
)
...
@@ -249,13 +251,16 @@ if(NOT CAF_BUILD_STATIC_ONLY)
...
@@ -249,13 +251,16 @@ if(NOT CAF_BUILD_STATIC_ONLY)
add_dependencies
(
libcaf_io libcaf_core
)
add_dependencies
(
libcaf_io libcaf_core
)
endif
()
endif
()
# set LIBCAF_LIBRARIES for other subprojects
# set LIBCAF_LIBRARIES for other subprojects
set
(
LIBCAF_LIBRARIES
${
LIBCAF_CORE_LIBRARY
}
${
LIBCAF_IO_LIBRARY
}
)
set
(
LIBCAF_LIBRARIES
${
LIBCAF_CORE_LIBRARY
}
${
LIBCAF_IO_LIBRARY
}
${
LIBCAF_OPENCL_LIBRARY
}
)
# add unit tests if not being told otherwise
# add unit tests if not being told otherwise
if
(
NOT CAF_NO_UNIT_TESTS
)
if
(
NOT CAF_NO_UNIT_TESTS
)
enable_testing
()
enable_testing
()
message
(
STATUS
"Enter subdirectory unit_testing"
)
message
(
STATUS
"Enter subdirectory unit_testing"
)
add_subdirectory
(
unit_testing
)
add_subdirectory
(
unit_testing
)
add_dependencies
(
all_unit_tests libcaf_io
)
add_dependencies
(
all_unit_tests libcaf_io
)
if
(
NOT CAF_NO_OPENCL AND EXISTS
"
${
CMAKE_SOURCE_DIR
}
/libcaf_opencl/caf"
)
add_subdirectory
(
libcaf_opencl/unit_testing
)
endif
()
endif
()
endif
()
# build examples if not being told otherwise
# build examples if not being told otherwise
if
(
NOT CAF_NO_EXAMPLES
)
if
(
NOT CAF_NO_EXAMPLES
)
...
@@ -310,6 +315,13 @@ if(NOT CAF_NO_PROBE AND EXISTS "${CMAKE_SOURCE_DIR}/probe/caf/")
...
@@ -310,6 +315,13 @@ if(NOT CAF_NO_PROBE AND EXISTS "${CMAKE_SOURCE_DIR}/probe/caf/")
set
(
CAF_NO_PROBE no
)
set
(
CAF_NO_PROBE no
)
endif
()
endif
()
endif
()
endif
()
# add probe-event if not told otherwise
if
(
NOT CAF_NO_PROBE_EVENT AND EXISTS
"
${
CMAKE_SOURCE_DIR
}
/probe-event/caf/"
)
message
(
STATUS
"Enter subdirectory probe-event"
)
add_subdirectory
(
probe-event
)
set
(
CAF_NO_PROBE_EVENT no
)
endif
()
# build benchmarks if not being told otherwise
# build benchmarks if not being told otherwise
if
(
NOT CAF_NO_BENCHMARKS AND EXISTS
"
${
CMAKE_SOURCE_DIR
}
/benchmarks/caf/"
)
if
(
NOT CAF_NO_BENCHMARKS AND EXISTS
"
${
CMAKE_SOURCE_DIR
}
/benchmarks/caf/"
)
message
(
STATUS
"Enter subdirectory benchmarks"
)
message
(
STATUS
"Enter subdirectory benchmarks"
)
...
...
FindOPENCL.cmake
0 → 100644
View file @
eb29971e
# - Try to find OpenCL
# Once done this will define
#
# OPENCL_FOUND - system has OpenCL
# OPENCL_INCLUDE_DIR - the OpenCL include directory
# OPENCL_LIBRARIES - link these to use OpenCL
#
# WIN32 should work, but is untested
IF
(
WIN32
)
FIND_PATH
(
OPENCL_INCLUDE_DIR CL/cl.h
)
# TODO this is only a hack assuming the 64 bit library will
# not be found on 32 bit system
FIND_LIBRARY
(
OPENCL_LIBRARIES opencl
)
#used to say opencl64
IF
(
OPENCL_LIBRARIES
)
FIND_LIBRARY
(
OPENCL_LIBRARIES opencl
)
#used to say opencl32
ENDIF
(
OPENCL_LIBRARIES
)
ELSE
(
WIN32
)
# Unix style platforms
# We also search for OpenCL in the NVIDIA GPU SDK default location
#SET(OPENCL_INCLUDE_DIR "$ENV{OPENCL_HOME}/common/inc"
# CACHE PATH "path to Opencl Include files")
#message(***** OPENCL_INCLUDE_DIR: "${OPENCL_INCLUDE_DIR}" ********)
# does not work. WHY?
#SET(inc $ENV{CUDA_LOCAL}/../OpenCL/common/inc /usr/include)
#FIND_PATH(OPENCL_INCLUDE_DIR CL/cl.h PATHS ${inc} /usr/include )
message
(
"lib path: $ENV{LD_LIBRARY_PATH}"
)
#FIND_LIBRARY(OPENCL_LIBRARIES OpenCL $ENV{LD_LIBRARY_PATH})
FIND_LIBRARY
(
OPENCL_LIBRARIES OpenCL ENV LD_LIBRARY_PATH
)
message
(
"=============="
)
message
(
"opencl_libraries:
${
OPENCL_LIBRARIES
}
"
)
#message(***** OPENCL ENV: "$ENV{GPU_SDK}" ********)
#~/NVIDIA_GPU_Computing_SDK/OpenCL/common/inc/
ENDIF
(
WIN32
)
SET
(
OPENCL_FOUND
"NO"
)
IF
(
OPENCL_LIBRARIES
)
SET
(
OPENCL_FOUND
"YES"
)
ENDIF
(
OPENCL_LIBRARIES
)
MARK_AS_ADVANCED
(
OPENCL_INCLUDE_DIR
)
examples/CMakeLists.txt
View file @
eb29971e
...
@@ -5,11 +5,11 @@ add_custom_target(all_examples)
...
@@ -5,11 +5,11 @@ add_custom_target(all_examples)
include_directories
(
${
LIBCAF_INCLUDE_DIRS
}
)
include_directories
(
${
LIBCAF_INCLUDE_DIRS
}
)
if
(
${
CMAKE_SYSTEM_NAME
}
MATCHES
"Window"
)
if
(
${
CMAKE_SYSTEM_NAME
}
MATCHES
"Window"
)
set
(
WSLIB -lws2_32
)
set
(
WSLIB -lws2_32
)
else
()
else
()
set
(
WSLIB
)
set
(
WSLIB
)
endif
()
endif
()
macro
(
add name folder
)
macro
(
add name folder
)
add_executable
(
${
name
}
${
folder
}
/
${
name
}
.cpp
${
ARGN
}
)
add_executable
(
${
name
}
${
folder
}
/
${
name
}
.cpp
${
ARGN
}
)
...
@@ -37,9 +37,9 @@ add(group_server remote_actors)
...
@@ -37,9 +37,9 @@ add(group_server remote_actors)
add
(
group_chat remote_actors
)
add
(
group_chat remote_actors
)
add
(
simple_broker remote_actors
)
add
(
simple_broker remote_actors
)
if
(
NOT
"
${
CAF_NO_PROTOBUF_EXAMPLES
}
"
STREQUAL
"yes"
)
if
(
NOT CAF_NO_PROTOBUF_EXAMPLES
)
find_package
(
Protobuf
)
find_package
(
Protobuf
)
if
(
PROTOBUF_FOUND AND PROTOBUF_PROTOC_EXECUTABLE
)
if
(
PROTOBUF_FOUND AND PROTOBUF_PROTOC_EXECUTABLE
)
PROTOBUF_GENERATE_CPP
(
ProtoSources ProtoHeaders
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/remote_actors/pingpong.proto"
)
PROTOBUF_GENERATE_CPP
(
ProtoSources ProtoHeaders
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/remote_actors/pingpong.proto"
)
include_directories
(
${
PROTOBUF_INCLUDE_DIR
}
)
include_directories
(
${
PROTOBUF_INCLUDE_DIR
}
)
# add binary dir as include path as generated headers will be located there
# add binary dir as include path as generated headers will be located there
...
@@ -47,14 +47,66 @@ if (NOT "${CAF_NO_PROTOBUF_EXAMPLES}" STREQUAL "yes")
...
@@ -47,14 +47,66 @@ if (NOT "${CAF_NO_PROTOBUF_EXAMPLES}" STREQUAL "yes")
add_executable
(
protobuf_broker remote_actors/protobuf_broker.cpp
${
ProtoSources
}
)
add_executable
(
protobuf_broker remote_actors/protobuf_broker.cpp
${
ProtoSources
}
)
target_link_libraries
(
protobuf_broker
${
CMAKE_DL_LIBS
}
${
LIBCAF_LIBRARIES
}
${
PTHREAD_LIBRARIES
}
${
PROTOBUF_LIBRARIES
}
)
target_link_libraries
(
protobuf_broker
${
CMAKE_DL_LIBS
}
${
LIBCAF_LIBRARIES
}
${
PTHREAD_LIBRARIES
}
${
PROTOBUF_LIBRARIES
}
)
add_dependencies
(
protobuf_broker all_examples
)
add_dependencies
(
protobuf_broker all_examples
)
endif
(
PROTOBUF_FOUND AND PROTOBUF_PROTOC_EXECUTABLE
)
endif
(
PROTOBUF_FOUND AND PROTOBUF_PROTOC_EXECUTABLE
)
endif
()
endif
()
if
(
NOT
"
${
CAF_NO_CURL_EXAMPLES
}
"
STREQUAL
"yes"
)
if
(
NOT CAF_NO_QT_EXAMPLES
)
find_package
(
Qt5 COMPONENTS Core Gui Widgets
)
if
(
Qt5_FOUND
)
message
(
STATUS
"Found Qt5"
)
#include(${QT_USE_FILE})
QT5_ADD_RESOURCES
(
GROUP_CHAT_RCS
)
QT5_WRAP_UI
(
GROUP_CHAT_UI_HDR qtsupport/chatwindow.ui
)
QT5_WRAP_CPP
(
GROUP_CHAT_MOC_SRC qtsupport/chatwidget.hpp
)
# generated headers will be in cmake build directory
#include_directories(. qtsupport ${CMAKE_CURRENT_BINARY_DIR} ${CPPA_INCLUDE})
include_directories
(
qtsupport
${
CMAKE_CURRENT_BINARY_DIR
}
${
Qt5Core_INCLUDE_DIRS
}
${
Qt5Gui_INCLUDE_DIRS
}
${
Qt5Widgets_INCLUDE_DIRS
}
)
set
(
GROUP_CHAT_SRC qtsupport/qt_group_chat.cpp qtsupport/chatwidget.cpp
)
add_executable
(
qt_group_chat
${
GROUP_CHAT_SRC
}
${
GROUP_CHAT_MOC_SRC
}
${
GROUP_CHAT_UI_HDR
}
)
target_link_libraries
(
qt_group_chat
${
CMAKE_DL_LIBS
}
${
LIBCAF_LIBRARIES
}
Qt5::Core
Qt5::Gui
Qt5::Widgets
)
add_dependencies
(
qt_group_chat all_examples
)
else
()
find_package
(
Qt4
)
if
(
QT4_FOUND
)
message
(
STATUS
"Found Qt4"
)
include
(
${
QT_USE_FILE
}
)
QT4_ADD_RESOURCES
(
GROUP_CHAT_RCS
)
QT4_WRAP_UI
(
GROUP_CHAT_UI_HDR qtsupport/chatwindow.ui
)
QT4_WRAP_CPP
(
GROUP_CHAT_MOC_SRC qtsupport/chatwidget.hpp
)
# generated headers will be in cmake build directory
#include_directories(. qtsupport ${CMAKE_CURRENT_BINARY_DIR} ${CPPA_INCLUDE})
include_directories
(
qtsupport
${
CMAKE_CURRENT_BINARY_DIR
}
)
set
(
GROUP_CHAT_SRCS qtsupport/qt_group_chat.cpp qtsupport/chatwidget.cpp
)
add_executable
(
qt_group_chat
${
GROUP_CHAT_SRCS
}
${
GROUP_CHAT_MOC_SRC
}
${
GROUP_CHAT_UI_HDR
}
)
target_link_libraries
(
qt_group_chat
${
CMAKE_DL_LIBS
}
${
LIBCAF_LIBRARIES
}
${
QT_LIBRARIES
}
)
add_dependencies
(
qt_group_chat all_examples
)
endif
()
endif
()
endif
()
if
(
NOT CAF_NO_CURL_EXAMPLES
)
find_package
(
CURL
)
find_package
(
CURL
)
if
(
CURL_FOUND
)
if
(
CURL_FOUND
)
add_executable
(
curl_fuse curl/curl_fuse.cpp
)
add_executable
(
curl_fuse curl/curl_fuse.cpp
)
target_link_libraries
(
curl_fuse
${
CMAKE_DL_LIBS
}
${
LIBCAF_LIBRARIES
}
${
PTHREAD_LIBRARIES
}
${
CURL_LIBRARY
}
)
target_link_libraries
(
curl_fuse
${
CMAKE_DL_LIBS
}
${
LIBCAF_LIBRARIES
}
${
PTHREAD_LIBRARIES
}
${
CURL_LIBRARY
}
)
add_dependencies
(
curl_fuse all_examples
)
add_dependencies
(
curl_fuse all_examples
)
endif
(
CURL_FOUND
)
endif
(
CURL_FOUND
)
endif
()
endif
()
examples/qtsupport/chatwidget.cpp
0 → 100644
View file @
eb29971e
#include <string>
#include <utility>
#include <QMessageBox>
#include <QInputDialog>
#include "chatwidget.hpp"
#include "caf/all.hpp"
#include "caf/detail/scope_guard.hpp"
using
namespace
std
;
using
namespace
caf
;
ChatWidget
::
ChatWidget
(
QWidget
*
parent
,
Qt
::
WindowFlags
f
)
:
super
(
parent
,
f
),
m_input
(
nullptr
),
m_output
(
nullptr
)
{
set_message_handler
([
=
](
local_actor
*
self
)
->
message_handler
{
return
{
on
(
atom
(
"join"
),
arg_match
)
>>
[
=
](
const
group
&
what
)
{
if
(
m_chatroom
)
{
self
->
send
(
m_chatroom
,
m_name
+
" has left the chatroom"
);
self
->
leave
(
m_chatroom
);
}
self
->
join
(
what
);
print
((
"*** joined "
+
to_string
(
what
)).
c_str
());
m_chatroom
=
what
;
self
->
send
(
what
,
m_name
+
" has entered the chatroom"
);
},
on
(
atom
(
"setName"
),
arg_match
)
>>
[
=
](
string
&
name
)
{
self
->
send
(
m_chatroom
,
m_name
+
" is now known as "
+
name
);
m_name
=
std
::
move
(
name
);
print
(
"*** changed name to "
+
QString
::
fromUtf8
(
m_name
.
c_str
()));
},
on
(
atom
(
"quit"
))
>>
[
=
]
{
close
();
// close widget
},
[
=
](
const
string
&
txt
)
{
// don't print own messages
if
(
self
!=
self
->
last_sender
())
{
print
(
QString
::
fromUtf8
(
txt
.
c_str
()));
}
},
[
=
](
const
group_down_msg
&
gdm
)
{
print
(
"*** chatroom offline: "
+
QString
::
fromUtf8
(
to_string
(
gdm
.
source
).
c_str
()));
}
};
});
}
void
ChatWidget
::
sendChatMessage
()
{
auto
cleanup
=
detail
::
make_scope_guard
([
=
]
{
input
()
->
setText
(
QString
());
});
QString
line
=
input
()
->
text
();
if
(
line
.
startsWith
(
'/'
))
{
match_split
(
line
.
midRef
(
1
).
toUtf8
().
constData
(),
' '
)
(
on
(
"join"
,
arg_match
)
>>
[
=
](
const
string
&
mod
,
const
string
&
g
)
{
group
gptr
;
try
{
gptr
=
group
::
get
(
mod
,
g
);
}
catch
(
exception
&
e
)
{
print
(
"*** exception: "
+
QString
::
fromUtf8
((
e
.
what
())));
}
if
(
gptr
)
{
send_as
(
as_actor
(),
as_actor
(),
atom
(
"join"
),
gptr
);
}
},
on
(
"setName"
,
arg_match
)
>>
[
=
](
const
string
&
str
)
{
send_as
(
as_actor
(),
as_actor
(),
atom
(
"setName"
),
str
);
},
others
()
>>
[
=
]
{
print
(
"*** list of commands:
\n
"
"/join <module> <group id>
\n
"
"/setName <new name>
\n
"
);
}
);
return
;
}
if
(
m_name
.
empty
())
{
print
(
"*** please set a name before sending messages"
);
return
;
}
if
(
!
m_chatroom
)
{
print
(
"*** no one is listening... please join a group"
);
return
;
}
string
msg
=
m_name
;
msg
+=
": "
;
msg
+=
line
.
toUtf8
().
constData
();
print
(
"<you>: "
+
input
()
->
text
());
// NOTE: we have to use send_as(as_actor(), ...) outside of our
// message handler, because `self` is *not* set properly
// in this context
send_as
(
as_actor
(),
m_chatroom
,
std
::
move
(
msg
));
}
void
ChatWidget
::
joinGroup
()
{
if
(
m_name
.
empty
())
{
QMessageBox
::
information
(
this
,
"No Name, No Chat"
,
"Please set a name first."
);
return
;
}
auto
gname
=
QInputDialog
::
getText
(
this
,
"Join Group"
,
"Please enter a group as <module>:<id>"
,
QLineEdit
::
Normal
,
"remote:chatroom@localhost:4242"
);
int
pos
=
gname
.
indexOf
(
':'
);
if
(
pos
<
0
)
{
QMessageBox
::
warning
(
this
,
"Not a Group"
,
"Invalid format"
);
return
;
}
string
mod
=
gname
.
left
(
pos
).
toUtf8
().
constData
();
string
gid
=
gname
.
midRef
(
pos
+
1
).
toUtf8
().
constData
();
try
{
auto
gptr
=
group
::
get
(
mod
,
gid
);
send_as
(
as_actor
(),
as_actor
(),
atom
(
"join"
),
gptr
);
}
catch
(
exception
&
e
)
{
QMessageBox
::
critical
(
this
,
"Exception"
,
e
.
what
());
}
}
void
ChatWidget
::
changeName
()
{
auto
name
=
QInputDialog
::
getText
(
this
,
"Change Name"
,
"Please enter a new name"
);
if
(
!
name
.
isEmpty
())
{
send_as
(
as_actor
(),
as_actor
(),
atom
(
"setName"
),
name
.
toUtf8
().
constData
());
}
}
examples/qtsupport/chatwidget.hpp
0 → 100644
View file @
eb29971e
#include <exception>
#include <QWidget>
#include <QLineEdit>
#include <QTextEdit>
#include "caf/all.hpp"
#include "caf/mixin/actor_widget.hpp"
class
ChatWidget
:
public
caf
::
mixin
::
actor_widget
<
QWidget
>
{
Q_OBJECT
typedef
caf
::
mixin
::
actor_widget
<
QWidget
>
super
;
public:
ChatWidget
(
QWidget
*
parent
=
nullptr
,
Qt
::
WindowFlags
f
=
0
);
public
slots
:
void
sendChatMessage
();
void
joinGroup
();
void
changeName
();
private:
template
<
typename
T
>
T
*
get
(
T
*&
member
,
const
char
*
name
)
{
if
(
member
==
nullptr
)
{
member
=
findChild
<
T
*>
(
name
);
if
(
member
==
nullptr
)
throw
std
::
runtime_error
(
"unable to find child: "
+
std
::
string
(
name
));
}
return
member
;
}
inline
QLineEdit
*
input
()
{
return
get
(
m_input
,
"input"
);
}
inline
QTextEdit
*
output
()
{
return
get
(
m_output
,
"output"
);
}
inline
void
print
(
const
QString
&
what
)
{
output
()
->
append
(
what
);
}
QLineEdit
*
m_input
;
QTextEdit
*
m_output
;
std
::
string
m_name
;
caf
::
group
m_chatroom
;
};
examples/qtsupport/chatwindow.ui
0 → 100644
View file @
eb29971e
<?xml version="1.0" encoding="UTF-8"?>
<ui
version=
"4.0"
>
<class>
ChatWindow
</class>
<widget
class=
"QMainWindow"
name=
"ChatWindow"
>
<property
name=
"geometry"
>
<rect>
<x>
0
</x>
<y>
0
</y>
<width>
800
</width>
<height>
600
</height>
</rect>
</property>
<property
name=
"windowTitle"
>
<string>
MainWindow
</string>
</property>
<widget
class=
"ChatWidget"
name=
"chatwidget"
>
<layout
class=
"QVBoxLayout"
name=
"verticalLayout"
>
<property
name=
"spacing"
>
<number>
0
</number>
</property>
<property
name=
"margin"
>
<number>
0
</number>
</property>
<item>
<widget
class=
"QTextEdit"
name=
"output"
>
<property
name=
"focusPolicy"
>
<enum>
Qt::ClickFocus
</enum>
</property>
<property
name=
"undoRedoEnabled"
>
<bool>
false
</bool>
</property>
<property
name=
"readOnly"
>
<bool>
true
</bool>
</property>
</widget>
</item>
<item>
<widget
class=
"QLineEdit"
name=
"input"
>
<property
name=
"focusPolicy"
>
<enum>
Qt::StrongFocus
</enum>
</property>
</widget>
</item>
<item>
<widget
class=
"QFrame"
name=
"frame"
>
<property
name=
"sizePolicy"
>
<sizepolicy
hsizetype=
"Minimum"
vsizetype=
"Preferred"
>
<horstretch>
0
</horstretch>
<verstretch>
0
</verstretch>
</sizepolicy>
</property>
<property
name=
"frameShape"
>
<enum>
QFrame::NoFrame
</enum>
</property>
<property
name=
"frameShadow"
>
<enum>
QFrame::Raised
</enum>
</property>
<property
name=
"lineWidth"
>
<number>
0
</number>
</property>
<layout
class=
"QHBoxLayout"
name=
"horizontalLayout_2"
>
<property
name=
"spacing"
>
<number>
0
</number>
</property>
<property
name=
"margin"
>
<number>
0
</number>
</property>
</layout>
</widget>
</item>
</layout>
</widget>
<widget
class=
"QMenuBar"
name=
"menubar"
>
<property
name=
"geometry"
>
<rect>
<x>
0
</x>
<y>
0
</y>
<width>
800
</width>
<height>
22
</height>
</rect>
</property>
<widget
class=
"QMenu"
name=
"menuFile"
>
<property
name=
"title"
>
<string>
File
</string>
</property>
<addaction
name=
"actionJoin_Group"
/>
<addaction
name=
"actionSet_Name"
/>
</widget>
<addaction
name=
"menuFile"
/>
</widget>
<action
name=
"actionJoin_Group"
>
<property
name=
"text"
>
<string>
Join Group
</string>
</property>
</action>
<action
name=
"actionSet_Name"
>
<property
name=
"text"
>
<string>
Set Name
</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>
ChatWidget
</class>
<extends>
QWidget
</extends>
<header>
chatwidget.hpp
</header>
<container>
1
</container>
<slots>
<slot>
sendChatMessage()
</slot>
<slot>
changeName()
</slot>
<slot>
joinGroup()
</slot>
</slots>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>
actionJoin_Group
</sender>
<signal>
activated()
</signal>
<receiver>
chatwidget
</receiver>
<slot>
joinGroup()
</slot>
<hints>
<hint
type=
"sourcelabel"
>
<x>
-1
</x>
<y>
-1
</y>
</hint>
<hint
type=
"destinationlabel"
>
<x>
399
</x>
<y>
300
</y>
</hint>
</hints>
</connection>
<connection>
<sender>
actionSet_Name
</sender>
<signal>
activated()
</signal>
<receiver>
chatwidget
</receiver>
<slot>
changeName()
</slot>
<hints>
<hint
type=
"sourcelabel"
>
<x>
-1
</x>
<y>
-1
</y>
</hint>
<hint
type=
"destinationlabel"
>
<x>
399
</x>
<y>
300
</y>
</hint>
</hints>
</connection>
<connection>
<sender>
input
</sender>
<signal>
returnPressed()
</signal>
<receiver>
chatwidget
</receiver>
<slot>
sendChatMessage()
</slot>
<hints>
<hint
type=
"sourcelabel"
>
<x>
362
</x>
<y>
547
</y>
</hint>
<hint
type=
"destinationlabel"
>
<x>
399
</x>
<y>
310
</y>
</hint>
</hints>
</connection>
</connections>
</ui>
examples/qtsupport/qt_group_chat.cpp
0 → 100755
View file @
eb29971e
/******************************************************************************\
* This example program represents a minimal GUI chat program *
* based on group communication. This chat program is compatible to the *
* terminal version in remote_actors/group_chat.cpp. *
* *
* Setup for a minimal chat between "alice" and "bob": *
* - ./build/bin/group_server -p 4242 *
* - ./build/bin/qt_group_chat -g remote:chatroom@localhost:4242 -n alice *
* - ./build/bin/qt_group_chat -g remote:chatroom@localhost:4242 -n bob *
\******************************************************************************/
#include <set>
#include <map>
#include <vector>
#include <iostream>
#include <sstream>
#include <time.h>
#include <cstdlib>
#include <QMainWindow>
#include <QApplication>
#include "caf/all.hpp"
#include "cppa/opt.hpp"
#include "ui_chatwindow.h" // auto generated from chatwindow.ui
using
namespace
std
;
using
namespace
caf
;
/*
namespace {
struct line { string str; };
istream& operator>>(istream& is, line& l) {
getline(is, l.str);
return is;
}
any_tuple s_last_line;
any_tuple split_line(const line& l) {
vector<string> result;
stringstream strs(l.str);
string tmp;
while (getline(strs, tmp, ' ')) {
if (!tmp.empty()) result.push_back(std::move(tmp));
}
s_last_line = any_tuple::view(std::move(result));
return s_last_line;
}
} // namespace <anonymous>
*/
int
main
(
int
argc
,
char
**
argv
)
{
string
name
;
string
group_id
;
options_description
desc
;
bool
args_valid
=
match_stream
<
string
>
(
argv
+
1
,
argv
+
argc
)
(
on_opt1
(
'n'
,
"name"
,
&
desc
,
"set name"
)
>>
rd_arg
(
name
),
on_opt1
(
'g'
,
"group"
,
&
desc
,
"join group <arg1>"
)
>>
rd_arg
(
group_id
),
on_opt0
(
'h'
,
"help"
,
&
desc
,
"print help"
)
>>
print_desc_and_exit
(
&
desc
)
);
group
gptr
;
// evaluate group parameter
if
(
!
group_id
.
empty
())
{
auto
p
=
group_id
.
find
(
':'
);
if
(
p
==
std
::
string
::
npos
)
{
cerr
<<
"*** error parsing argument "
<<
group_id
<<
", expected format: <module_name>:<group_id>"
;
}
else
{
try
{
gptr
=
group
::
get
(
group_id
.
substr
(
0
,
p
),
group_id
.
substr
(
p
+
1
));
}
catch
(
exception
&
e
)
{
ostringstream
err
;
cerr
<<
"*** exception: group::get(
\"
"
<<
group_id
.
substr
(
0
,
p
)
<<
"
\"
,
\"
"
<<
group_id
.
substr
(
p
+
1
)
<<
"
\"
) failed; "
<<
to_verbose_string
(
e
)
<<
endl
;
}
}
}
if
(
!
args_valid
)
print_desc_and_exit
(
&
desc
)();
QApplication
app
(
argc
,
argv
);
app
.
setQuitOnLastWindowClosed
(
true
);
QMainWindow
mw
;
Ui
::
ChatWindow
helper
;
helper
.
setupUi
(
&
mw
);
auto
client
=
helper
.
chatwidget
->
as_actor
();
if
(
!
name
.
empty
())
{
send_as
(
client
,
client
,
atom
(
"setName"
),
move
(
name
));
}
if
(
gptr
)
{
send_as
(
client
,
client
,
atom
(
"join"
),
gptr
);
}
mw
.
show
();
auto
res
=
app
.
exec
();
shutdown
();
await_all_actors_done
();
return
res
;
}
libcaf_core/caf/detail/default_uniform_type_info.hpp
View file @
eb29971e
...
@@ -30,9 +30,9 @@
...
@@ -30,9 +30,9 @@
#include "caf/deserializer.hpp"
#include "caf/deserializer.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/detail/types_array.hpp"
#include "caf/detail/abstract_uniform_type_info.hpp"
#include "caf/detail/abstract_uniform_type_info.hpp"
#include "caf/detail/types_array.hpp"
namespace
caf
{
namespace
caf
{
namespace
detail
{
namespace
detail
{
...
@@ -48,11 +48,9 @@ long sfinae_has_push_back(void*); // SFNINAE default
...
@@ -48,11 +48,9 @@ long sfinae_has_push_back(void*); // SFNINAE default
template
<
class
T
>
template
<
class
T
>
struct
is_stl_compliant_list
{
struct
is_stl_compliant_list
{
static
constexpr
bool
value
=
static
constexpr
bool
value
=
detail
::
is_iterable
<
T
>::
value
&&
detail
::
is_iterable
<
T
>::
value
sizeof
(
sfinae_has_push_back
(
static_cast
<
T
*>
(
nullptr
)))
==
sizeof
(
char
);
&&
sizeof
(
sfinae_has_push_back
(
static_cast
<
T
*>
(
nullptr
)))
==
sizeof
(
char
);
};
};
// check if there's an 'insert' that takes a C::value_type
// check if there's an 'insert' that takes a C::value_type
...
@@ -64,40 +62,46 @@ long sfinae_has_insert(void*); // SFNINAE default
...
@@ -64,40 +62,46 @@ long sfinae_has_insert(void*); // SFNINAE default
template
<
class
T
>
template
<
class
T
>
struct
is_stl_compliant_map
{
struct
is_stl_compliant_map
{
static
constexpr
bool
value
=
static
constexpr
bool
value
=
detail
::
is_iterable
<
T
>::
value
&&
detail
::
is_iterable
<
T
>::
value
sizeof
(
sfinae_has_insert
(
static_cast
<
T
*>
(
nullptr
)))
==
sizeof
(
char
);
&&
sizeof
(
sfinae_has_insert
(
static_cast
<
T
*>
(
nullptr
)))
==
sizeof
(
char
);
};
};
template
<
class
T
>
template
<
class
T
>
struct
is_stl_pair
:
std
::
false_type
{};
struct
is_stl_pair
:
std
::
false_type
{
// no members
};
template
<
class
F
,
typename
S
>
template
<
class
F
,
typename
S
>
struct
is_stl_pair
<
std
::
pair
<
F
,
S
>>
:
std
::
true_type
{};
struct
is_stl_pair
<
std
::
pair
<
F
,
S
>>
:
std
::
true_type
{
// no members
};
using
primitive_impl
=
std
::
integral_constant
<
int
,
0
>
;
using
primitive_impl
=
std
::
integral_constant
<
int
,
0
>
;
using
list_impl
=
std
::
integral_constant
<
int
,
1
>
;
using
list_impl
=
std
::
integral_constant
<
int
,
1
>
;
using
map_impl
=
std
::
integral_constant
<
int
,
2
>
;
using
map_impl
=
std
::
integral_constant
<
int
,
2
>
;
using
pair_impl
=
std
::
integral_constant
<
int
,
3
>
;
using
pair_impl
=
std
::
integral_constant
<
int
,
3
>
;
using
opt_impl
=
std
::
integral_constant
<
int
,
4
>
;
using
recursive_impl
=
std
::
integral_constant
<
int
,
9
>
;
using
recursive_impl
=
std
::
integral_constant
<
int
,
9
>
;
template
<
class
T
>
template
<
class
T
>
constexpr
int
impl_id
()
{
constexpr
int
impl_id
()
{
return
detail
::
is_primitive
<
T
>::
value
?
return
detail
::
is_primitive
<
T
>::
value
0
:
?
0
(
is_stl_compliant_list
<
T
>::
value
?
:
(
is_stl_compliant_list
<
T
>::
value
1
:
?
1
(
is_stl_compliant_map
<
T
>::
value
?
:
(
is_stl_compliant_map
<
T
>::
value
2
:
?
2
(
is_stl_pair
<
T
>::
value
?
3
:
9
)));
:
(
is_stl_pair
<
T
>::
value
?
3
:
(
detail
::
is_optional
<
T
>::
value
?
4
:
9
))));
}
}
template
<
class
T
>
template
<
class
T
>
struct
deconst_pair
{
struct
deconst_pair
{
using
type
=
T
;
using
type
=
T
;
};
};
template
<
class
K
,
typename
V
>
template
<
class
K
,
typename
V
>
...
@@ -105,13 +109,10 @@ struct deconst_pair<std::pair<K, V>> {
...
@@ -105,13 +109,10 @@ struct deconst_pair<std::pair<K, V>> {
using
first_type
=
typename
std
::
remove_const
<
K
>::
type
;
using
first_type
=
typename
std
::
remove_const
<
K
>::
type
;
using
second_type
=
typename
std
::
remove_const
<
V
>::
type
;
using
second_type
=
typename
std
::
remove_const
<
V
>::
type
;
using
type
=
std
::
pair
<
first_type
,
second_type
>
;
using
type
=
std
::
pair
<
first_type
,
second_type
>
;
};
};
class
default_serialize_policy
{
class
default_serialize_policy
{
public:
public:
template
<
class
T
>
template
<
class
T
>
void
operator
()(
const
T
&
val
,
serializer
*
s
)
const
{
void
operator
()(
const
T
&
val
,
serializer
*
s
)
const
{
std
::
integral_constant
<
int
,
impl_id
<
T
>
()
>
token
;
std
::
integral_constant
<
int
,
impl_id
<
T
>
()
>
token
;
...
@@ -122,11 +123,9 @@ class default_serialize_policy {
...
@@ -122,11 +123,9 @@ class default_serialize_policy {
void
operator
()(
T
&
val
,
deserializer
*
d
)
const
{
void
operator
()(
T
&
val
,
deserializer
*
d
)
const
{
std
::
integral_constant
<
int
,
impl_id
<
T
>
()
>
token
;
std
::
integral_constant
<
int
,
impl_id
<
T
>
()
>
token
;
dimpl
(
val
,
d
,
token
);
dimpl
(
val
,
d
,
token
);
// static_types_array<T>::arr[0]->deserialize(&val, d);
}
}
private:
private:
template
<
class
T
>
template
<
class
T
>
void
simpl
(
const
T
&
val
,
serializer
*
s
,
primitive_impl
)
const
{
void
simpl
(
const
T
&
val
,
serializer
*
s
,
primitive_impl
)
const
{
s
->
write_value
(
val
);
s
->
write_value
(
val
);
...
@@ -154,6 +153,15 @@ class default_serialize_policy {
...
@@ -154,6 +153,15 @@ class default_serialize_policy {
(
*
this
)(
val
.
second
,
s
);
(
*
this
)(
val
.
second
,
s
);
}
}
template
<
class
T
>
void
simpl
(
const
optional
<
T
>&
val
,
serializer
*
s
,
opt_impl
)
const
{
uint8_t
flag
=
val
?
1
:
0
;
s
->
write_value
(
flag
);
if
(
val
)
{
(
*
this
)(
*
val
,
s
);
}
}
template
<
class
T
>
template
<
class
T
>
void
simpl
(
const
T
&
val
,
serializer
*
s
,
recursive_impl
)
const
{
void
simpl
(
const
T
&
val
,
serializer
*
s
,
recursive_impl
)
const
{
static_types_array
<
T
>::
arr
[
0
]
->
serialize
(
&
val
,
s
);
static_types_array
<
T
>::
arr
[
0
]
->
serialize
(
&
val
,
s
);
...
@@ -195,19 +203,30 @@ class default_serialize_policy {
...
@@ -195,19 +203,30 @@ class default_serialize_policy {
(
*
this
)(
storage
.
second
,
d
);
(
*
this
)(
storage
.
second
,
d
);
}
}
template
<
class
T
>
void
dimpl
(
optional
<
T
>&
val
,
deserializer
*
d
,
opt_impl
)
const
{
auto
flag
=
d
->
read
<
uint8_t
>
();
if
(
flag
!=
0
)
{
T
tmp
;
(
*
this
)(
tmp
,
d
);
val
=
std
::
move
(
tmp
);
}
else
{
val
=
none
;
}
}
template
<
class
T
>
template
<
class
T
>
void
dimpl
(
T
&
storage
,
deserializer
*
d
,
recursive_impl
)
const
{
void
dimpl
(
T
&
storage
,
deserializer
*
d
,
recursive_impl
)
const
{
static_types_array
<
T
>::
arr
[
0
]
->
deserialize
(
&
storage
,
d
);
static_types_array
<
T
>::
arr
[
0
]
->
deserialize
(
&
storage
,
d
);
}
}
};
};
class
forwarding_serialize_policy
{
class
forwarding_serialize_policy
{
public:
public:
inline
forwarding_serialize_policy
(
uniform_type_info_ptr
uti
)
inline
forwarding_serialize_policy
(
uniform_type_info_ptr
uti
)
:
m_uti
(
std
::
move
(
uti
))
{}
:
m_uti
(
std
::
move
(
uti
))
{
// nop
}
template
<
class
T
>
template
<
class
T
>
void
operator
()(
const
T
&
val
,
serializer
*
s
)
const
{
void
operator
()(
const
T
&
val
,
serializer
*
s
)
const
{
...
@@ -220,9 +239,7 @@ class forwarding_serialize_policy {
...
@@ -220,9 +239,7 @@ class forwarding_serialize_policy {
}
}
private:
private:
uniform_type_info_ptr
m_uti
;
uniform_type_info_ptr
m_uti
;
};
};
template
<
class
T
,
class
AccessPolicy
,
template
<
class
T
,
class
AccessPolicy
,
...
@@ -230,15 +247,17 @@ template <class T, class AccessPolicy,
...
@@ -230,15 +247,17 @@ template <class T, class AccessPolicy,
bool
IsEnum
=
std
::
is_enum
<
T
>
::
value
,
bool
IsEnum
=
std
::
is_enum
<
T
>
::
value
,
bool
IsEmptyType
=
std
::
is_class
<
T
>::
value
&&
std
::
is_empty
<
T
>::
value
>
bool
IsEmptyType
=
std
::
is_class
<
T
>::
value
&&
std
::
is_empty
<
T
>::
value
>
class
member_tinfo
:
public
detail
::
abstract_uniform_type_info
<
T
>
{
class
member_tinfo
:
public
detail
::
abstract_uniform_type_info
<
T
>
{
public:
public:
member_tinfo
(
AccessPolicy
apol
,
SerializePolicy
spol
)
member_tinfo
(
AccessPolicy
apol
,
SerializePolicy
spol
)
:
m_apol
(
std
::
move
(
apol
)),
m_spol
(
std
::
move
(
spol
))
{}
:
m_apol
(
std
::
move
(
apol
)),
m_spol
(
std
::
move
(
spol
))
{
// nop
}
member_tinfo
(
AccessPolicy
apol
)
:
m_apol
(
std
::
move
(
apol
))
{}
member_tinfo
(
AccessPolicy
apol
)
:
m_apol
(
std
::
move
(
apol
))
{
// nop
}
member_tinfo
()
{}
member_tinfo
()
=
default
;
void
serialize
(
const
void
*
vptr
,
serializer
*
s
)
const
override
{
void
serialize
(
const
void
*
vptr
,
serializer
*
s
)
const
override
{
m_spol
(
m_apol
(
vptr
),
s
);
m_spol
(
m_apol
(
vptr
),
s
);
...
@@ -278,9 +297,7 @@ class member_tinfo<T, A, S, false, true>
...
@@ -278,9 +297,7 @@ class member_tinfo<T, A, S, false, true>
// nop
// nop
}
}
member_tinfo
()
{
member_tinfo
()
=
default
;
// nop
}
void
serialize
(
const
void
*
,
serializer
*
)
const
override
{
void
serialize
(
const
void
*
,
serializer
*
)
const
override
{
// nop
// nop
...
@@ -294,16 +311,15 @@ class member_tinfo<T, A, S, false, true>
...
@@ -294,16 +311,15 @@ class member_tinfo<T, A, S, false, true>
template
<
class
T
,
class
AccessPolicy
,
class
SerializePolicy
>
template
<
class
T
,
class
AccessPolicy
,
class
SerializePolicy
>
class
member_tinfo
<
T
,
AccessPolicy
,
SerializePolicy
,
true
,
false
>
class
member_tinfo
<
T
,
AccessPolicy
,
SerializePolicy
,
true
,
false
>
:
public
detail
::
abstract_uniform_type_info
<
T
>
{
:
public
detail
::
abstract_uniform_type_info
<
T
>
{
public:
using
value_type
=
typename
std
::
underlying_type
<
T
>::
type
;
using
value_type
=
typename
std
::
underlying_type
<
T
>::
type
;
public:
member_tinfo
(
AccessPolicy
apol
,
SerializePolicy
spol
)
member_tinfo
(
AccessPolicy
apol
,
SerializePolicy
spol
)
:
m_apol
(
std
::
move
(
apol
)),
m_spol
(
std
::
move
(
spol
))
{}
:
m_apol
(
std
::
move
(
apol
)),
m_spol
(
std
::
move
(
spol
))
{}
member_tinfo
(
AccessPolicy
apol
)
:
m_apol
(
std
::
move
(
apol
))
{}
member_tinfo
(
AccessPolicy
apol
)
:
m_apol
(
std
::
move
(
apol
))
{}
member_tinfo
()
{}
member_tinfo
()
=
default
;
void
serialize
(
const
void
*
p
,
serializer
*
s
)
const
override
{
void
serialize
(
const
void
*
p
,
serializer
*
s
)
const
override
{
auto
val
=
m_apol
(
p
);
auto
val
=
m_apol
(
p
);
...
@@ -319,18 +335,17 @@ class member_tinfo<T, AccessPolicy, SerializePolicy, true, false>
...
@@ -319,18 +335,17 @@ class member_tinfo<T, AccessPolicy, SerializePolicy, true, false>
private:
private:
AccessPolicy
m_apol
;
AccessPolicy
m_apol
;
SerializePolicy
m_spol
;
SerializePolicy
m_spol
;
};
};
template
<
class
T
,
class
C
>
template
<
class
T
,
class
C
>
class
memptr_access_policy
{
class
memptr_access_policy
{
public:
public:
inline
memptr_access_policy
(
T
C
::*
memptr
)
:
m_memptr
(
memptr
)
{
// nop
}
memptr_access_policy
(
const
memptr_access_policy
&
)
=
default
;
memptr_access_policy
(
const
memptr_access_policy
&
)
=
default
;
memptr_access_policy
&
operator
=
(
const
memptr_access_policy
&
)
=
default
;
memptr_access_policy
&
operator
=
(
const
memptr_access_policy
&
)
=
default
;
inline
memptr_access_policy
(
T
C
::*
memptr
)
:
m_memptr
(
memptr
)
{}
inline
T
&
operator
()(
void
*
vptr
)
const
{
inline
T
&
operator
()(
void
*
vptr
)
const
{
auto
ptr
=
reinterpret_cast
<
C
*>
(
vptr
);
auto
ptr
=
reinterpret_cast
<
C
*>
(
vptr
);
return
*
ptr
.
*
m_memptr
;
return
*
ptr
.
*
m_memptr
;
...
@@ -355,7 +370,6 @@ class memptr_access_policy {
...
@@ -355,7 +370,6 @@ class memptr_access_policy {
template
<
class
C
,
typename
GRes
,
typename
SRes
,
typename
SArg
>
template
<
class
C
,
typename
GRes
,
typename
SRes
,
typename
SArg
>
class
getter_setter_access_policy
{
class
getter_setter_access_policy
{
public:
public:
using
getter
=
GRes
(
C
::*
)()
const
;
using
getter
=
GRes
(
C
::*
)()
const
;
...
@@ -377,15 +391,12 @@ class getter_setter_access_policy {
...
@@ -377,15 +391,12 @@ class getter_setter_access_policy {
static
constexpr
bool
grants_mutable_access
=
false
;
static
constexpr
bool
grants_mutable_access
=
false
;
private:
private:
getter
m_get
;
getter
m_get
;
setter
m_set
;
setter
m_set
;
};
};
template
<
class
T
>
template
<
class
T
>
struct
fake_access_policy
{
struct
fake_access_policy
{
inline
T
&
operator
()(
void
*
vptr
)
const
{
inline
T
&
operator
()(
void
*
vptr
)
const
{
return
*
reinterpret_cast
<
T
*>
(
vptr
);
return
*
reinterpret_cast
<
T
*>
(
vptr
);
}
}
...
@@ -400,7 +411,6 @@ struct fake_access_policy {
...
@@ -400,7 +411,6 @@ struct fake_access_policy {
}
}
static
constexpr
bool
grants_mutable_access
=
true
;
static
constexpr
bool
grants_mutable_access
=
true
;
};
};
template
<
class
T
,
class
C
>
template
<
class
T
,
class
C
>
...
@@ -436,15 +446,13 @@ uniform_type_info_ptr new_member_tinfo(GRes (C::*getter)() const,
...
@@ -436,15 +446,13 @@ uniform_type_info_ptr new_member_tinfo(GRes (C::*getter)() const,
using
value_type
=
typename
detail
::
rm_const_and_ref
<
GRes
>::
type
;
using
value_type
=
typename
detail
::
rm_const_and_ref
<
GRes
>::
type
;
using
tinfo
=
member_tinfo
<
value_type
,
access_policy
,
using
tinfo
=
member_tinfo
<
value_type
,
access_policy
,
forwarding_serialize_policy
>
;
forwarding_serialize_policy
>
;
return
uniform_type_info_ptr
(
return
uniform_type_info_ptr
(
new
tinfo
(
access_policy
(
getter
,
setter
),
new
tinfo
(
access_policy
(
getter
,
setter
),
std
::
move
(
meminf
)));
std
::
move
(
meminf
)));
}
}
template
<
class
T
>
template
<
class
T
>
class
default_uniform_type_info
:
public
detail
::
abstract_uniform_type_info
<
T
>
{
class
default_uniform_type_info
:
public
detail
::
abstract_uniform_type_info
<
T
>
{
public:
public:
template
<
class
...
Ts
>
template
<
class
...
Ts
>
default_uniform_type_info
(
Ts
&&
...
args
)
{
default_uniform_type_info
(
Ts
&&
...
args
)
{
push_back
(
std
::
forward
<
Ts
>
(
args
)...);
push_back
(
std
::
forward
<
Ts
>
(
args
)...);
...
@@ -457,22 +465,24 @@ class default_uniform_type_info : public detail::abstract_uniform_type_info<T> {
...
@@ -457,22 +465,24 @@ class default_uniform_type_info : public detail::abstract_uniform_type_info<T> {
void
serialize
(
const
void
*
obj
,
serializer
*
s
)
const
override
{
void
serialize
(
const
void
*
obj
,
serializer
*
s
)
const
override
{
// serialize each member
// serialize each member
for
(
auto
&
m
:
m_members
)
m
->
serialize
(
obj
,
s
);
for
(
auto
&
m
:
m_members
)
{
m
->
serialize
(
obj
,
s
);
}
}
}
void
deserialize
(
void
*
obj
,
deserializer
*
d
)
const
override
{
void
deserialize
(
void
*
obj
,
deserializer
*
d
)
const
override
{
// deserialize each member
// deserialize each member
for
(
auto
&
m
:
m_members
)
m
->
deserialize
(
obj
,
d
);
for
(
auto
&
m
:
m_members
)
{
m
->
deserialize
(
obj
,
d
);
}
}
}
protected:
protected:
bool
pod_mems_equals
(
const
T
&
lhs
,
const
T
&
rhs
)
const
override
{
bool
pod_mems_equals
(
const
T
&
lhs
,
const
T
&
rhs
)
const
override
{
return
pod_eq
(
lhs
,
rhs
);
return
pod_eq
(
lhs
,
rhs
);
}
}
private:
private:
template
<
class
C
>
template
<
class
C
>
typename
std
::
enable_if
<
std
::
is_pod
<
C
>::
value
,
bool
>::
type
typename
std
::
enable_if
<
std
::
is_pod
<
C
>::
value
,
bool
>::
type
pod_eq
(
const
C
&
lhs
,
const
C
&
rhs
)
const
{
pod_eq
(
const
C
&
lhs
,
const
C
&
rhs
)
const
{
...
@@ -488,8 +498,9 @@ class default_uniform_type_info : public detail::abstract_uniform_type_info<T> {
...
@@ -488,8 +498,9 @@ class default_uniform_type_info : public detail::abstract_uniform_type_info<T> {
return
false
;
return
false
;
}
}
// terminates recursion
inline
void
push_back
()
{
inline
void
push_back
()
{}
// terminate recursion
}
template
<
class
R
,
class
C
,
class
...
Ts
>
template
<
class
R
,
class
C
,
class
...
Ts
>
void
push_back
(
R
C
::*
memptr
,
Ts
&&
...
args
)
{
void
push_back
(
R
C
::*
memptr
,
Ts
&&
...
args
)
{
...
@@ -535,18 +546,17 @@ class default_uniform_type_info : public detail::abstract_uniform_type_info<T> {
...
@@ -535,18 +546,17 @@ class default_uniform_type_info : public detail::abstract_uniform_type_info<T> {
}
}
std
::
vector
<
uniform_type_info_ptr
>
m_members
;
std
::
vector
<
uniform_type_info_ptr
>
m_members
;
};
};
template
<
class
...
Rs
>
template
<
class
...
Rs
>
class
default_uniform_type_info
<
typed_actor
<
class
default_uniform_type_info
<
typed_actor
<
Rs
...
>>
:
Rs
...
>>
:
public
detail
::
abstract_uniform_type_info
<
typed_actor
<
Rs
...
>>
{
public
detail
::
abstract_uniform_type_info
<
typed_actor
<
Rs
...
>>
{
public:
public:
using
handle_type
=
typed_actor
<
Rs
...
>
;
using
handle_type
=
typed_actor
<
Rs
...
>
;
default_uniform_type_info
()
{
sub_uti
=
uniform_typeid
<
actor
>
();
}
default_uniform_type_info
()
{
sub_uti
=
uniform_typeid
<
actor
>
();
}
void
serialize
(
const
void
*
obj
,
serializer
*
s
)
const
override
{
void
serialize
(
const
void
*
obj
,
serializer
*
s
)
const
override
{
auto
tmp
=
actor_cast
<
actor
>
(
deref
(
obj
).
address
());
auto
tmp
=
actor_cast
<
actor
>
(
deref
(
obj
).
address
());
...
@@ -560,17 +570,13 @@ class default_uniform_type_info<typed_actor<
...
@@ -560,17 +570,13 @@ class default_uniform_type_info<typed_actor<
}
}
private:
private:
const
uniform_type_info
*
sub_uti
;
static
handle_type
&
deref
(
void
*
ptr
)
{
static
handle_type
&
deref
(
void
*
ptr
)
{
return
*
reinterpret_cast
<
handle_type
*>
(
ptr
);
return
*
reinterpret_cast
<
handle_type
*>
(
ptr
);
}
}
static
const
handle_type
&
deref
(
const
void
*
ptr
)
{
static
const
handle_type
&
deref
(
const
void
*
ptr
)
{
return
*
reinterpret_cast
<
const
handle_type
*>
(
ptr
);
return
*
reinterpret_cast
<
const
handle_type
*>
(
ptr
);
}
}
const
uniform_type_info
*
sub_uti
;
};
};
}
// namespace detail
}
// namespace detail
...
...
libcaf_core/caf/detail/type_traits.hpp
View file @
eb29971e
...
@@ -479,6 +479,16 @@ struct type_at<0, T0, Ts...> {
...
@@ -479,6 +479,16 @@ struct type_at<0, T0, Ts...> {
using
type
=
T0
;
using
type
=
T0
;
};
};
template
<
class
T
>
struct
is_optional
:
std
::
false_type
{
// no members
};
template
<
class
T
>
struct
is_optional
<
optional
<
T
>>
:
std
::
true_type
{
// no members
};
}
// namespace detail
}
// namespace detail
}
// namespace caf
}
// namespace caf
...
...
libcaf_core/caf/mixin/actor_widget.hpp
0 → 100644
View file @
eb29971e
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011-2013 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcaf. *
* libcaf 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. *
* *
* libcaf 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 libcaf. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef CPPA_ACTOR_WIDGET_MIXIN_HPP
#define CPPA_ACTOR_WIDGET_MIXIN_HPP
#include <QEvent>
#include <QApplication>
#include "caf/actor_companion.hpp"
#include "caf/message_handler.hpp"
#include "caf/policy/sequential_invoke.hpp"
namespace
caf
{
namespace
mixin
{
template
<
typename
Base
,
int
EventId
=
static_cast
<
int
>(
QEvent
::
User
+
31337
)
>
class
actor_widget
:
public
Base
{
public:
typedef
typename
actor_companion
::
message_pointer
message_pointer
;
struct
event_type
:
public
QEvent
{
message_pointer
mptr
;
event_type
(
message_pointer
ptr
)
:
QEvent
(
static_cast
<
QEvent
::
Type
>
(
EventId
)),
mptr
(
std
::
move
(
ptr
))
{
}
};
template
<
typename
...
Ts
>
actor_widget
(
Ts
&&
...
args
)
:
Base
(
std
::
forward
<
Ts
>
(
args
)...)
{
m_companion
.
reset
(
detail
::
memory
::
create
<
actor_companion
>
());
m_companion
->
on_enqueue
([
=
](
message_pointer
ptr
)
{
qApp
->
postEvent
(
this
,
new
event_type
(
std
::
move
(
ptr
)));
});
}
template
<
typename
T
>
void
set_message_handler
(
T
pfun
)
{
m_companion
->
become
(
pfun
(
m_companion
.
get
()));
}
virtual
bool
event
(
QEvent
*
event
)
{
if
(
event
->
type
()
==
static_cast
<
QEvent
::
Type
>
(
EventId
))
{
auto
ptr
=
dynamic_cast
<
event_type
*>
(
event
);
if
(
ptr
)
{
m_invoke
.
handle_message
(
m_companion
.
get
(),
ptr
->
mptr
.
release
(),
m_companion
->
bhvr_stack
().
back
(),
m_companion
->
bhvr_stack
().
back_id
());
return
true
;
}
}
return
Base
::
event
(
event
);
}
actor
as_actor
()
const
{
return
m_companion
;
}
private:
policy
::
sequential_invoke
m_invoke
;
actor_companion_ptr
m_companion
;
};
}
// namespace mixin
}
// namespace caf
#endif // CPPA_ACTOR_WIDGET_MIXIN_HPP
libcaf_core/caf/on.hpp
View file @
eb29971e
...
@@ -335,19 +335,13 @@ struct to_guard<anything, false> {
...
@@ -335,19 +335,13 @@ struct to_guard<anything, false> {
template
<
class
T
>
template
<
class
T
>
struct
to_guard
<
detail
::
wrapped
<
T
>
,
false
>
:
to_guard
<
anything
>
{};
struct
to_guard
<
detail
::
wrapped
<
T
>
,
false
>
:
to_guard
<
anything
>
{};
template
<
class
T
>
struct
is_optional
:
std
::
false_type
{};
template
<
class
T
>
struct
is_optional
<
optional
<
T
>>
:
std
::
true_type
{};
template
<
class
T
>
template
<
class
T
>
struct
to_guard
<
T
,
true
>
{
struct
to_guard
<
T
,
true
>
{
using
ct
=
typename
detail
::
get_callable_trait
<
T
>::
type
;
using
ct
=
typename
detail
::
get_callable_trait
<
T
>::
type
;
using
arg_types
=
typename
ct
::
arg_types
;
using
arg_types
=
typename
ct
::
arg_types
;
static_assert
(
detail
::
tl_size
<
arg_types
>::
value
==
1
,
static_assert
(
detail
::
tl_size
<
arg_types
>::
value
==
1
,
"projection/guard must take exactly one argument"
);
"projection/guard must take exactly one argument"
);
static_assert
(
is_optional
<
typename
ct
::
result_type
>::
value
,
static_assert
(
detail
::
is_optional
<
typename
ct
::
result_type
>::
value
,
"projection/guard must return an optional value"
);
"projection/guard must return an optional value"
);
using
value_type
=
using
value_type
=
typename
std
::
conditional
<
typename
std
::
conditional
<
...
@@ -355,8 +349,9 @@ struct to_guard<T, true> {
...
@@ -355,8 +349,9 @@ struct to_guard<T, true> {
T
*
,
T
*
,
T
T
>::
type
;
>::
type
;
static
value_type
_
(
value_type
val
)
{
return
val
;
}
static
value_type
_
(
value_type
val
)
{
return
val
;
}
};
};
template
<
class
T
>
template
<
class
T
>
...
...
libcaf_io/caf/io/hook.hpp
View file @
eb29971e
...
@@ -84,14 +84,14 @@ class hook {
...
@@ -84,14 +84,14 @@ class hook {
* Called whenever a message is forwarded to a different node.
* Called whenever a message is forwarded to a different node.
*/
*/
virtual
void
message_forwarded_cb
(
const
node_id
&
from
,
const
node_id
&
dest
,
virtual
void
message_forwarded_cb
(
const
node_id
&
from
,
const
node_id
&
dest
,
std
::
vector
<
char
>*
payload
);
const
std
::
vector
<
char
>*
payload
);
/**
/**
* Called whenever no route for a forwarding request exists.
* Called whenever no route for a forwarding request exists.
*/
*/
virtual
void
message_forwarding_failed_cb
(
const
node_id
&
from
,
virtual
void
message_forwarding_failed_cb
(
const
node_id
&
from
,
const
node_id
&
to
,
const
node_id
&
to
,
std
::
vector
<
char
>*
payload
);
const
std
::
vector
<
char
>*
payload
);
/**
/**
* Called whenever an actor has been published.
* Called whenever an actor has been published.
...
...
libcaf_io/caf/io/publish_impl.hpp
View file @
eb29971e
...
@@ -32,15 +32,16 @@ namespace caf {
...
@@ -32,15 +32,16 @@ namespace caf {
namespace
io
{
namespace
io
{
template
<
class
ActorHandle
,
class
SocketAcceptor
>
template
<
class
ActorHandle
,
class
SocketAcceptor
>
void
publish_impl
(
ActorHandle
whom
,
SocketAcceptor
fd
)
{
void
publish_impl
(
ActorHandle
whom
,
SocketAcceptor
fd
,
uint16_t
port
)
{
using
namespace
detail
;
using
namespace
detail
;
auto
mm
=
middleman
::
instance
();
auto
mm
=
middleman
::
instance
();
// we can't move fd into our lambda in C++11 ...
// we can't move fd into our lambda in C++11 ...
using
pair_type
=
std
::
pair
<
ActorHandle
,
SocketAcceptor
>
;
using
pair_type
=
std
::
pair
<
ActorHandle
,
SocketAcceptor
>
;
auto
data
=
std
::
make_shared
<
pair_type
>
(
std
::
move
(
whom
)
,
std
::
move
(
fd
));
auto
data
=
std
::
make_shared
<
pair_type
>
(
whom
,
std
::
move
(
fd
));
mm
->
run_later
([
mm
,
data
]
{
mm
->
run_later
([
mm
,
data
,
whom
,
port
]
{
auto
bro
=
mm
->
get_named_broker
<
basp_broker
>
(
atom
(
"_BASP"
));
auto
bro
=
mm
->
get_named_broker
<
basp_broker
>
(
atom
(
"_BASP"
));
bro
->
publish
(
std
::
move
(
data
->
first
),
std
::
move
(
data
->
second
));
bro
->
publish
(
std
::
move
(
data
->
first
),
std
::
move
(
data
->
second
));
mm
->
notify
<
hook
::
actor_published
>
(
whom
->
address
(),
port
);
});
});
}
}
...
@@ -48,10 +49,9 @@ inline void publish_impl(abstract_actor_ptr whom, uint16_t port,
...
@@ -48,10 +49,9 @@ inline void publish_impl(abstract_actor_ptr whom, uint16_t port,
const
char
*
ipaddr
)
{
const
char
*
ipaddr
)
{
using
namespace
detail
;
using
namespace
detail
;
auto
mm
=
middleman
::
instance
();
auto
mm
=
middleman
::
instance
();
auto
addr
=
whom
->
address
();
network
::
default_socket_acceptor
fd
{
mm
->
backend
()};
network
::
default_socket_acceptor
fd
{
mm
->
backend
()};
network
::
ipv4_bind
(
fd
,
port
,
ipaddr
);
network
::
ipv4_bind
(
fd
,
port
,
ipaddr
);
publish_impl
(
std
::
move
(
whom
),
std
::
move
(
fd
));
publish_impl
(
std
::
move
(
whom
),
std
::
move
(
fd
)
,
port
);
}
}
}
// namespace io
}
// namespace io
...
...
libcaf_io/src/basp_broker.cpp
View file @
eb29971e
...
@@ -261,9 +261,10 @@ basp_broker::handle_basp_header(connection_context& ctx,
...
@@ -261,9 +261,10 @@ basp_broker::handle_basp_header(connection_context& ctx,
if
(
hdr
.
dest_node
!=
invalid_node_id
&&
hdr
.
dest_node
!=
node
())
{
if
(
hdr
.
dest_node
!=
invalid_node_id
&&
hdr
.
dest_node
!=
node
())
{
auto
route
=
get_route
(
hdr
.
dest_node
);
auto
route
=
get_route
(
hdr
.
dest_node
);
if
(
route
.
invalid
())
{
if
(
route
.
invalid
())
{
// TODO: signalize that we don't have route to given node
CAF_LOG_INFO
(
"message dropped: no route to node "
CAF_LOG_INFO
(
"message dropped: no route to node "
<<
to_string
(
hdr
.
dest_node
));
<<
to_string
(
hdr
.
dest_node
));
parent
().
notify
<
hook
::
message_forwarding_failed
>
(
hdr
.
source_node
,
hdr
.
dest_node
,
payload
);
return
close_connection
;
return
close_connection
;
}
}
auto
&
buf
=
wr_buf
(
route
.
hdl
);
auto
&
buf
=
wr_buf
(
route
.
hdl
);
...
@@ -271,6 +272,8 @@ basp_broker::handle_basp_header(connection_context& ctx,
...
@@ -271,6 +272,8 @@ basp_broker::handle_basp_header(connection_context& ctx,
write
(
bs
,
hdr
);
write
(
bs
,
hdr
);
if
(
payload
)
buf
.
insert
(
buf
.
end
(),
payload
->
begin
(),
payload
->
end
());
if
(
payload
)
buf
.
insert
(
buf
.
end
(),
payload
->
begin
(),
payload
->
end
());
flush
(
route
.
hdl
);
flush
(
route
.
hdl
);
parent
().
notify
<
hook
::
message_forwarded
>
(
hdr
.
source_node
,
hdr
.
dest_node
,
payload
);
return
await_header
;
return
await_header
;
}
}
// handle a message that is addressed to us
// handle a message that is addressed to us
...
@@ -334,6 +337,7 @@ basp_broker::handle_basp_header(connection_context& ctx,
...
@@ -334,6 +337,7 @@ basp_broker::handle_basp_header(connection_context& ctx,
CAF_LOG_INFO
(
"multiple incoming connections from the same node"
);
CAF_LOG_INFO
(
"multiple incoming connections from the same node"
);
return
close_connection
;
return
close_connection
;
}
}
parent
().
notify
<
hook
::
new_connection_established
>
(
ctx
.
remote_id
);
break
;
break
;
}
}
case
basp
:
:
server_handshake
:
{
case
basp
:
:
server_handshake
:
{
...
@@ -427,6 +431,7 @@ basp_broker::handle_basp_header(connection_context& ctx,
...
@@ -427,6 +431,7 @@ basp_broker::handle_basp_header(connection_context& ctx,
ctx
.
published_actor
=
proxy
;
ctx
.
published_actor
=
proxy
;
ctx
.
handshake_data
->
result
->
set_value
(
std
::
move
(
proxy
));
ctx
.
handshake_data
->
result
->
set_value
(
std
::
move
(
proxy
));
ctx
.
handshake_data
=
nullptr
;
ctx
.
handshake_data
=
nullptr
;
parent
().
notify
<
hook
::
new_connection_established
>
(
nid
);
break
;
break
;
}
}
}
}
...
@@ -516,6 +521,7 @@ void basp_broker::erase_proxy(const id_type& nid, actor_id aid) {
...
@@ -516,6 +521,7 @@ void basp_broker::erase_proxy(const id_type& nid, actor_id aid) {
void
basp_broker
::
add_route
(
const
id_type
&
nid
,
connection_handle
hdl
)
{
void
basp_broker
::
add_route
(
const
id_type
&
nid
,
connection_handle
hdl
)
{
if
(
m_blacklist
.
count
(
std
::
make_pair
(
nid
,
hdl
))
==
0
)
{
if
(
m_blacklist
.
count
(
std
::
make_pair
(
nid
,
hdl
))
==
0
)
{
parent
().
notify
<
hook
::
new_route_added
>
(
m_current_context
->
remote_id
,
nid
);
m_routes
[
nid
].
second
.
insert
({
hdl
,
nid
});
m_routes
[
nid
].
second
.
insert
({
hdl
,
nid
});
}
}
}
}
...
...
libcaf_io/src/hook.cpp
View file @
eb29971e
...
@@ -41,7 +41,7 @@ void hook::message_sent_cb(const actor_addr& from, const node_id& dest_node,
...
@@ -41,7 +41,7 @@ void hook::message_sent_cb(const actor_addr& from, const node_id& dest_node,
}
}
void
hook
::
message_forwarded_cb
(
const
node_id
&
from
,
const
node_id
&
dest
,
void
hook
::
message_forwarded_cb
(
const
node_id
&
from
,
const
node_id
&
dest
,
std
::
vector
<
char
>*
payload
)
{
const
std
::
vector
<
char
>*
payload
)
{
call_next
<
message_forwarded
>
(
from
,
dest
,
payload
);
call_next
<
message_forwarded
>
(
from
,
dest
,
payload
);
}
}
...
@@ -53,7 +53,7 @@ void hook::message_sending_failed_cb(const actor_addr& from,
...
@@ -53,7 +53,7 @@ void hook::message_sending_failed_cb(const actor_addr& from,
}
}
void
hook
::
message_forwarding_failed_cb
(
const
node_id
&
from
,
const
node_id
&
to
,
void
hook
::
message_forwarding_failed_cb
(
const
node_id
&
from
,
const
node_id
&
to
,
std
::
vector
<
char
>*
payload
)
{
const
std
::
vector
<
char
>*
payload
)
{
call_next
<
message_forwarding_failed
>
(
from
,
to
,
payload
);
call_next
<
message_forwarding_failed
>
(
from
,
to
,
payload
);
}
}
...
...
unit_testing/test_opencl.cpp
deleted
100644 → 0
View file @
6a8fd3e5
#include <vector>
#include <iomanip>
#include <cassert>
#include <iostream>
#include <algorithm>
#include "test.hpp"
#include "cppa/cppa.hpp"
#include "cppa/opencl.hpp"
using
namespace
std
;
using
namespace
cppa
;
using
namespace
cppa
::
opencl
;
namespace
{
using
ivec
=
vector
<
int
>
;
using
fvec
=
vector
<
float
>
;
constexpr
size_t
matrix_size
=
4
;
constexpr
size_t
array_size
=
32
;
constexpr
int
magic_number
=
23
;
constexpr
const
char
*
kernel_name
=
"matrix_square"
;
constexpr
const
char
*
kernel_name_compiler_flag
=
"compiler_flag"
;
constexpr
const
char
*
kernel_name_reduce
=
"reduce"
;
constexpr
const
char
*
kernel_name_const
=
"const_mod"
;
constexpr
const
char
*
compiler_flag
=
"-D OPENCL_CPPA_TEST_FLAG"
;
constexpr
const
char
*
kernel_source
=
R"__(
__kernel void matrix_square(__global int* matrix,
__global int* output) {
size_t size = get_global_size(0); // == get_global_size_(1);
size_t x = get_global_id(0);
size_t y = get_global_id(1);
int result = 0;
for (size_t idx = 0; idx < size; ++idx) {
result += matrix[idx + y * size] * matrix[x + idx * size];
}
output[x + y * size] = result;
}
)__"
;
constexpr
const
char
*
kernel_source_error
=
R"__(
__kernel void missing(__global int*) {
size_t semicolon
}
)__"
;
constexpr
const
char
*
kernel_source_compiler_flag
=
R"__(
__kernel void compiler_flag(__global int* input,
__global int* output) {
size_t x = get_global_id(0);
#ifdef OPENCL_CPPA_TEST_FLAG
output[x] = input[x];
#else
output[x] = 0;
#endif
}
)__"
;
// http://developer.amd.com/resources/documentation-articles/articles-whitepapers/
// opencl-optimization-case-study-simple-reductions
constexpr
const
char
*
kernel_source_reduce
=
R"__(
__kernel void reduce(__global int* buffer,
__global int* result) {
__local int scratch[512];
int local_index = get_local_id(0);
scratch[local_index] = buffer[get_global_id(0)];
barrier(CLK_LOCAL_MEM_FENCE);
for(int offset = get_local_size(0) / 2; offset > 0; offset = offset / 2) {
if (local_index < offset) {
int other = scratch[local_index + offset];
int mine = scratch[local_index];
scratch[local_index] = (mine < other) ? mine : other;
}
barrier(CLK_LOCAL_MEM_FENCE);
}
if (local_index == 0) {
result[get_group_id(0)] = scratch[0];
}
}
)__"
;
constexpr
const
char
*
kernel_source_const
=
R"__(
__kernel void const_mod(__constant int* input,
__global int* output) {
size_t idx = get_global_id(0);
output[idx] = input[0];
}
)__"
;
}
template
<
size_t
Size
>
class
square_matrix
{
public:
static
constexpr
size_t
num_elements
=
Size
*
Size
;
static
void
announce
()
{
cppa
::
announce
<
square_matrix
>
(
&
square_matrix
::
m_data
);
}
square_matrix
(
square_matrix
&&
)
=
default
;
square_matrix
(
const
square_matrix
&
)
=
default
;
square_matrix
&
operator
=
(
square_matrix
&&
)
=
default
;
square_matrix
&
operator
=
(
const
square_matrix
&
)
=
default
;
square_matrix
()
:
m_data
(
num_elements
)
{
}
explicit
square_matrix
(
ivec
d
)
:
m_data
(
move
(
d
))
{
assert
(
m_data
.
size
()
==
num_elements
);
}
inline
float
&
operator
()(
size_t
column
,
size_t
row
)
{
return
m_data
[
column
+
row
*
Size
];
}
inline
const
float
&
operator
()(
size_t
column
,
size_t
row
)
const
{
return
m_data
[
column
+
row
*
Size
];
}
inline
void
iota_fill
()
{
iota
(
m_data
.
begin
(),
m_data
.
end
(),
0
);
}
typedef
typename
ivec
::
const_iterator
const_iterator
;
const_iterator
begin
()
const
{
return
m_data
.
begin
();
}
const_iterator
end
()
const
{
return
m_data
.
end
();
}
ivec
&
data
()
{
return
m_data
;
}
const
ivec
&
data
()
const
{
return
m_data
;
}
void
data
(
ivec
new_data
)
{
m_data
=
std
::
move
(
new_data
);
}
private:
ivec
m_data
;
};
template
<
size_t
Size
>
inline
bool
operator
==
(
const
square_matrix
<
Size
>&
lhs
,
const
square_matrix
<
Size
>&
rhs
)
{
return
equal
(
lhs
.
begin
(),
lhs
.
end
(),
rhs
.
begin
());
}
template
<
size_t
Size
>
inline
bool
operator
!=
(
const
square_matrix
<
Size
>&
lhs
,
const
square_matrix
<
Size
>&
rhs
)
{
return
!
(
lhs
==
rhs
);
}
using
matrix_type
=
square_matrix
<
matrix_size
>
;
size_t
get_max_workgroup_size
(
size_t
device_id
,
size_t
dimension
)
{
size_t
max_size
=
512
;
auto
devices
=
get_opencl_metainfo
()
->
get_devices
()[
device_id
];
size_t
dimsize
=
devices
.
get_max_work_items_per_dim
()[
dimension
];
return
max_size
<
dimsize
?
max_size
:
dimsize
;
}
void
test_opencl
()
{
scoped_actor
self
;
const
ivec
expected1
{
56
,
62
,
68
,
74
,
152
,
174
,
196
,
218
,
248
,
286
,
324
,
362
,
344
,
398
,
452
,
506
};
auto
worker1
=
spawn_cl
<
ivec
(
ivec
&
)
>
(
program
::
create
(
kernel_source
),
kernel_name
,
{
matrix_size
,
matrix_size
});
ivec
m1
(
matrix_size
*
matrix_size
);
iota
(
begin
(
m1
),
end
(
m1
),
0
);
self
->
send
(
worker1
,
move
(
m1
));
self
->
receive
(
on_arg_match
>>
[
&
]
(
const
ivec
&
result
)
{
CPPA_CHECK
(
equal
(
begin
(
expected1
),
end
(
expected1
),
begin
(
result
)));
}
);
auto
worker2
=
spawn_cl
<
ivec
(
ivec
&
)
>
(
kernel_source
,
kernel_name
,
{
matrix_size
,
matrix_size
});
ivec
m2
(
matrix_size
*
matrix_size
);
iota
(
begin
(
m2
),
end
(
m2
),
0
);
self
->
send
(
worker2
,
move
(
m2
));
self
->
receive
(
on_arg_match
>>
[
&
]
(
const
ivec
&
result
)
{
CPPA_CHECK
(
equal
(
begin
(
expected1
),
end
(
expected1
),
begin
(
result
)));
}
);
const
matrix_type
expected2
(
move
(
expected1
));
auto
map_args
=
[]
(
any_tuple
msg
)
->
optional
<
cow_tuple
<
ivec
>>
{
auto
opt
=
tuple_cast
<
matrix_type
>
(
msg
);
if
(
opt
)
{
return
make_cow_tuple
(
move
(
get_ref
<
0
>
(
*
opt
).
data
()));
}
return
none
;
};
auto
map_results
=
[]
(
ivec
&
result
)
->
any_tuple
{
return
make_any_tuple
(
matrix_type
{
move
(
result
)});
};
matrix_type
m3
;
m3
.
iota_fill
();
auto
worker3
=
spawn_cl
(
program
::
create
(
kernel_source
),
kernel_name
,
map_args
,
map_results
,
{
matrix_size
,
matrix_size
});
self
->
send
(
worker3
,
move
(
m3
));
self
->
receive
(
on_arg_match
>>
[
&
]
(
const
matrix_type
&
result
)
{
CPPA_CHECK
(
expected2
==
result
);
}
);
matrix_type
m4
;
m4
.
iota_fill
();
auto
worker4
=
spawn_cl
(
kernel_source
,
kernel_name
,
map_args
,
map_results
,
{
matrix_size
,
matrix_size
}
);
self
->
send
(
worker4
,
move
(
m4
));
self
->
receive
(
on_arg_match
>>
[
&
]
(
const
matrix_type
&
result
)
{
CPPA_CHECK
(
expected2
==
result
);
}
);
try
{
program
create_error
=
program
::
create
(
kernel_source_error
);
}
catch
(
const
exception
&
exc
)
{
cout
<<
exc
.
what
()
<<
endl
;
CPPA_CHECK_EQUAL
(
"clBuildProgram: CL_BUILD_PROGRAM_FAILURE"
,
exc
.
what
());
}
// test for opencl compiler flags
ivec
arr5
(
array_size
);
iota
(
begin
(
arr5
),
end
(
arr5
),
0
);
auto
prog5
=
program
::
create
(
kernel_source_compiler_flag
,
compiler_flag
);
auto
worker5
=
spawn_cl
<
ivec
(
ivec
&
)
>
(
prog5
,
kernel_name_compiler_flag
,
{
array_size
});
self
->
send
(
worker5
,
move
(
arr5
));
ivec
expected3
(
array_size
);
iota
(
begin
(
expected3
),
end
(
expected3
),
0
);
self
->
receive
(
on_arg_match
>>
[
&
]
(
const
ivec
&
result
)
{
CPPA_CHECK
(
equal
(
begin
(
expected3
),
end
(
expected3
),
begin
(
result
)));
}
);
// test for manuel return size selection
const
int
max_workgroup_size
=
static_cast
<
int
>
(
get_max_workgroup_size
(
0
,
1
));
// max workgroup size (1d)
const
size_t
reduce_buffer_size
=
max_workgroup_size
*
8
;
const
size_t
reduce_local_size
=
max_workgroup_size
;
const
size_t
reduce_work_groups
=
reduce_buffer_size
/
reduce_local_size
;
const
size_t
reduce_global_size
=
reduce_buffer_size
;
const
size_t
reduce_result_size
=
reduce_work_groups
;
ivec
arr6
(
reduce_buffer_size
);
int
n
{
static_cast
<
int
>
(
arr6
.
capacity
())};
generate
(
begin
(
arr6
),
end
(
arr6
),
[
&
]{
return
--
n
;
});
auto
worker6
=
spawn_cl
<
ivec
(
ivec
&
)
>
(
kernel_source_reduce
,
kernel_name_reduce
,
{
reduce_global_size
},
{},
{
reduce_local_size
},
reduce_result_size
);
self
->
send
(
worker6
,
move
(
arr6
));
const
ivec
expected4
{
max_workgroup_size
*
7
,
max_workgroup_size
*
6
,
max_workgroup_size
*
5
,
max_workgroup_size
*
4
,
max_workgroup_size
*
3
,
max_workgroup_size
*
2
,
max_workgroup_size
,
0
};
self
->
receive
(
on_arg_match
>>
[
&
]
(
const
ivec
&
result
)
{
CPPA_CHECK
(
equal
(
begin
(
expected4
),
end
(
expected4
),
begin
(
result
)));
}
);
// constant memory arguments
const
ivec
arr7
{
magic_number
};
auto
worker7
=
spawn_cl
<
ivec
(
ivec
&
)
>
(
kernel_source_const
,
kernel_name_const
,
{
magic_number
});
self
->
send
(
worker7
,
move
(
arr7
));
ivec
expected5
(
magic_number
);
fill
(
begin
(
expected5
),
end
(
expected5
),
magic_number
);
self
->
receive
(
on_arg_match
>>
[
&
]
(
const
ivec
&
result
)
{
CPPA_CHECK
(
equal
(
begin
(
expected5
),
end
(
expected5
),
begin
(
result
)));
}
);
}
int
main
()
{
CPPA_TEST
(
tkest_opencl
);
announce
<
ivec
>
();
matrix_type
::
announce
();
test_opencl
();
await_all_actors_done
();
shutdown
();
return
CPPA_TEST_RESULT
();
}
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