void bs2_benchmark() { Rng_t rng; Eng_t eng (0, 100); chrono_timer timer; boost::signals2::signal<void(Rng_t&)> signal_one; boost::signals2::signal<void(std::size_t, Rng_t&)> signal_two; // N = 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192 for (std::size_t N = 16; N <= 128; N *= 2) // magic numbers are globals { Width_t sum_previous = 1; Width_t sum_current = 2; Width_t sum_count = 0; // loop until wrap around occurs or until max count is reached while (sum_previous < sum_current && sum_count < 100) { // try to randomize access patterns std::vector<std::size_t> random_index(N); std::generate(random_index.begin(), random_index.end(), IncrementFill()); std::shuffle(random_index.begin(), random_index.end(), rng); // delay seems to increase timing accuracy sum_previous = sum_current; timer.delay(10); timer.reset(); { // time boost::signals2::trackable construction overhead std::vector<Bs2> obj(N); for (std::size_t index : random_index) { // what is the next operation? connect or emit if (eng(rng) > 50) { Bs2* ptr = &obj[index]; signal_one.connect(boost::bind(&Bs2::method_one, ptr, _1)); signal_two.connect(boost::bind(&Bs2::method_two, ptr, _1, _2)); } else { signal_one(rng); signal_two(index, rng); } } } sum_current += timer.elapsed_us(); ++sum_count; } // calculate milliseconds and output the relative performance double elapsed_ms = (sum_previous / (double)sum_count) * 0.001; std::cout << (N / elapsed_ms) << std::endl; } std::cout << Bs2::s_sum << std::endl; }
int main() { // Declare Nano::Signals using function signature syntax Nano::Signal<bool(const char*)> signal_one; Nano::Signal<bool(const char*, std::size_t)> signal_two; // Test void slot types Nano::Signal<void()> signal_three; signal_three.connect<handler_e>(); signal_three.emit(); // Test using function objects std::function<bool(const char*, std::size_t)> fo; fo = [&](const char* sl, std::size_t ln) { std::cout << sl << " [on line: " << ln << "]" << std::endl; // Test indirectly disconnecting the currently emitting slot signal_two.disconnect(fo); return true; }; // Create a new scope to test automatic disconnect { Foo foo; // Connect member functions to Nano::Signals signal_one.connect<Foo, &Foo::handler_a>(&foo); signal_two.connect<Foo, &Foo::handler_b>(&foo); // Connect a static member function signal_one.connect<Foo::handler_c>(); // Connect a free function signal_two.connect<handler_d>(); // Emit Signals signal_one.emit("we get signal"); signal_two.emit("main screen turn on", __LINE__); std::vector<bool> status; // Emit Signals and accumulate SRVs (signal return values) signal_one.emit_accumulate([&](bool srv) { status.push_back(srv); } ,"how are you gentlemen"); // Disconnect member functions from a Nano::Signal signal_one.disconnect<Foo, &Foo::handler_a>(foo); signal_two.disconnect<Foo, &Foo::handler_b>(foo); // Disconnect a static member function signal_one.disconnect<Foo::handler_c>(); // Disconnect a free function signal_two.disconnect<handler_d>(); // Emit again to test disconnects signal_one.emit("THIS SHOULD NOT APPEAR"); signal_two.emit("THIS SHOULD NOT APPEAR", __LINE__); // Connecting function objects (or any object defining a suitable operator()) signal_two.connect(&fo); // Test indirectly disconnecting the currently emitting slot signal_two.emit("indirect disconnect", __LINE__); // Disconnecting function objects (test convenience overload) signal_two.disconnect(fo); // Test auto disconnect signal_one.connect<Foo, &Foo::handler_a>(foo); } // If this appears then automatic disconnect did not work signal_one.emit("THIS SHOULD NOT APPEAR"); #ifdef NANO_USE_DEPRECATED // Test deprecated emit interface signal_one("we get signal"); signal_two("main screen turn on", __LINE__); std::vector<bool> status; // Emit Signals and accumulate SRVs (signal return values) signal_one("how are you gentlemen", [&](bool srv) { status.push_back(srv); }); #endif // Pause the screen std::cin.get(); }