# Sigslot, a signal-slot library
Sigslot is a header-only, thread safe implementation of signal-slots for C++.
## Features
The main goal was to replace Boost.Signals2.
Apart from the usual features, it offers
- Thread safety,
- Object lifetime tracking for automatic slot disconnection (extensible through ADL),
- RAII connection management,
- Slot groups to enforce slots execution order,
- Reasonable performance. and a simple and straightforward implementation.
Sigslot is unit-tested and should be reliable and stable enough to replace Boost Signals2.
The tests run cleanly under the address, thread and undefined behaviour sanitizers.
Many implementations allow signal return types, Sigslot does not because I have
no use for them. If I can be convinced of otherwise I may change my mind later on.
## Installation
No compilation or installation is required, just include `sigslot/signal.hpp`
and use it. Sigslot currently depends on a C++14 compliant compiler, but if need
arises it may be retrofitted to C++11. It is known to work with Clang 4.0 and GCC
5.0+ compilers on GNU Linux, MSVC 2017 and up, Clang-cl and MinGW on Windows.
However, be aware of a potential gotcha on Windows with MSVC and Clang-Cl compilers,
which may need the `/OPT:NOICF` linker flags in exceptional situations. Read The
Implementation Details chapter for an explanation.
A CMake list file is supplied for installation purpose and generating a CMake import
module. This is the preferred installation method. The `Pal::Sigslot` imported target
is available and already applies the needed linker flags. It is also required for
examples and tests, which optionally depend on Qt5 and Boost for adapters unit tests.
```cmake
# Using Sigslot from cmake
find_package(PalSigslot)
add_executable(MyExe main.cpp)
target_link_libraries(MyExe PRIVATE Pal::Sigslot)
```
A configuration option `SIGSLOT_REDUCE_COMPILE_TIME` is available at configuration
time. When activated, it attempts to reduce code bloat by avoiding heavy template
instantiations resulting from calls to `std::make_shared`.
This option is off by default, but can be activated for those who wish to favor
code size and compilation time at the expanse of slightly less efficient code.
Installation may be done using the following instructions from the root directory:
```sh
mkdir build && cd build
cmake .. -DSIGSLOT_REDUCE_COMPILE_TIME=ON -DCMAKE_INSTALL_PREFIX=~/local
cmake --build . --target install
# If you want to compile examples:
cmake --build . --target sigslot-examples
# And compile/execute unit tests:
cmake --build . --target sigslot-tests
```
### CMake FetchContent
`Pal::Sigslot` can also be integrated using the [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) method.
```cmake
include(FetchContent)
FetchContent_Declare(
sigslot
GIT_REPOSITORY https://github.com/palacaze/sigslot
GIT_TAG 19a6f0f5ea11fc121fe67f81fd5e491f2d7a4637 # v1.2.0
)
FetchContent_MakeAvailable(sigslot)
add_executable(MyExe main.cpp)
target_link_libraries(MyExe PRIVATE Pal::Sigslot)
```
## Documentation
Sigslot implements the signal-slot construct popular in UI frameworks, making it
easy to use the observer pattern or event-based programming. The main entry point
of the library is the `sigslot::signal<T...>` class template.
A signal is an object that can emit typed notifications, really values parametrized
after the signal class template parameters, and register any number of notification
handlers (callables) of compatible argument types to be executed with the values
supplied whenever a signal emission happens. In signal-slot parlance this is called
connecting a slot to a signal, where a "slot" represents a callable instance and
a "connection" can be thought of as a conceptual link from signal to slot.
All the snippets presented below are available in compilable source code form in
the example subdirectory.
### Basic usage
Here is a first example that showcases the most basic features of the library.
We first declare a parameter-free signal `sig`, then we proceed to connect several
slots and at last emit a signal which triggers the invocation of every slot callable
connected beforehand. Notice how The library handles diverse forms of callables.
```cpp
#include <sigslot/signal.hpp>
#include <iostream>
void f() { std::cout << "free function\n"; }
struct s {
void m() { std::cout << "member function\n"; }
static void sm() { std::cout << "static member function\n"; }
};
struct o {
void operator()() { std::cout << "function object\n"; }
};
int main() {
s d;
auto lambda = []() { std::cout << "lambda\n"; };
auto gen_lambda = [](auto && ...a) { std::cout << "generic lambda\n"; };
// declare a signal instance with no arguments
sigslot::signal<> sig;
// connect slots
sig.connect(f);
sig.connect(&s::m, &d);
sig.connect(&s::sm);
sig.connect(o());
sig.connect(lambda);
sig.connect(gen_lambda);
// emit a signal
sig();
}
```
By default, the slot invocation order when emitting a signal is unspecified, please
do not rely on it being always the same. You may constrain a particular invocation
order by using slot groups, which are presented later on.
### Signal with arguments
That first example was simple but not so useful, let us move on to a signal that
emits values instead. A signal can emit any number of arguments, below.
```cpp
#include <sigslot/signal.hpp>
#include <iostream>
#include <string>
struct foo {
// Notice how we accept a double as first argument here.
// This is fine because float is convertible to double.
// 's' is a reference and can thus be modified.
void bar(double d, int i, bool b, std::string &s) {
s = b ? std::to_string(i) : std::to_string(d);
}
};
// Function objects can cope with default arguments and overloading.
// It does not work with static and member functions.
struct obj {
void operator()(float, int, bool, std::string &, int = 0) {
std::cout << "I was here\n";
}
void operator()() {}
};
int main() {
// declare a signal with float, int, bool and string& arguments
sigslot::signal<float, int, bool, std::string&> sig;
// a generic lambda that prints its arguments to stdout
auto printer = [] (auto a, auto && ...args) {
std::cout << a;
(void)std::initializer_list<int>{
((void)(std::cout << " " << args), 1)...
};
std::cout << "\n";
};
// connect the slots
foo ff;
sig.connect(printer);
sig.connect(&foo::bar, &ff);
sig.connect(obj());
float f = 1.f;
short i = 2; // convertible to int
std::string s = "0";
// emit a signal
sig(f, i, false, s);
sig(f, i, true, s);
}
```
As shown, slots arguments types don't need to be strictly identical to the signal
template parameters, being convertible-from is fine. Generic arguments are fine too,
as shown with the `printer` generic lambda (which could have been written as a
function template too).
Right now there are two limitations that I can think of with respect to callable
handling: default arguments and function overloading. Both are working correctly
in the case of function objects but will fail to compile with static and member
functions, for different but related reasons.
#### Coping with overloaded functions
Consider the following piece of code:
```cpp
struct foo {
void bar(double d);
void bar();
};
```
What should `&foo::bar` refer to? As per overloading, this pointer over member
function does not map to a unique symbol, so the compiler won't be able to pick
the right symbol. One way of resolving the right symbol is to explicitly cast the
function pointer to the right function type. Here is an example that does just that
using a little helper tool for a lighter syntax (In fact I will probably add this
to the library soon).
```cpp
#include <sigslot/signal.hpp>
template <typename... Args, typename C>
c
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
Pangolin-0.8-x64-windows.zip (217个子文件)
PangolinTargets.cmake 8KB
PangolinTargets-debug.cmake 7KB
PangolinConfig.cmake 729B
PangolinConfigVersion.cmake 642B
VideoViewer.exe 6.61MB
VideoConvert.exe 6.09MB
Plotter.exe 4.16MB
VideoJsonTransform.exe 3.93MB
VideoJsonPrint.exe 3.85MB
tiny_obj_loader.h 76KB
picojson.h 40KB
glsl.h 25KB
gldraw.h 15KB
opengl_render_state.h 13KB
image.h 11KB
display_android.h 10KB
simple_math.h 10KB
gl2engine.h 10KB
varstate.h 9KB
gl.h 9KB
glcuda.h 9KB
plotter.h 8KB
firewire.h 8KB
factory_registry.h 8KB
view.h 8KB
range.h 7KB
cg.h 7KB
image_utils.h 7KB
glvbo.h 7KB
datalog.h 7KB
glformattraits.h 6KB
sync_time.h 6KB
scenehandler.h 6KB
video_interface.h 6KB
glstate.h 6KB
video.h 6KB
display.h 5KB
colour.h 5KB
packetstream_writer.h 5KB
handler.h 5KB
file_utils.h 5KB
depthsense.h 5KB
handler_image.h 5KB
widgets.h 5KB
openni2.h 5KB
fix_size_buffer_queue.h 5KB
pleora.h 5KB
type_convert.h 5KB
managed_image.h 4KB
geometry_ply.h 4KB
openni_common.h 4KB
video_input.h 4KB
var.h 4KB
window.h 4KB
glpixformat.h 4KB
gltexturecache.h 4KB
debayer.h 4KB
varvalue.h 4KB
iostream_operators.h 4KB
images.h 4KB
shared_image.h 4KB
v4l.h 4KB
teli.h 4KB
uvc.h 4KB
ffmpeg_common.h 3KB
stream_info.h 3KB
thread.h 3KB
axis.h 3KB
ffmpeg_output.h 3KB
pango.h 3KB
params.h 3KB
video_output.h 3KB
ffmpeg.h 3KB
varvaluegeneric.h 3KB
memcpy.h 3KB
ffmpeg_convert.h 3KB
transform.h 3KB
ConsoleView.h 3KB
parse.h 3KB
timer.h 3KB
X11Window.h 3KB
geometry.h 3KB
glutbitmap.h 3KB
attach.h 3KB
glgeometry.h 3KB
handler_enums.h 3KB
transform.h 3KB
packetstream_reader.h 3KB
threadedfilebuf.h 3KB
uvc_mediafoundation.h 3KB
assert.h 3KB
format_string.h 3KB
join.h 3KB
image_io.h 3KB
varextra.h 3KB
glplatform.h 3KB
gltext.h 3KB
varinit.h 3KB
gamma.h 3KB
packetstream.h 3KB
共 217 条
- 1
- 2
- 3
资源评论
azh-1415926
- 粉丝: 17
- 资源: 22
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功