Skip to content

Commit 42c295a

Browse files
authored
check for removed observer (#13)
* check for removed observer * update Readme
1 parent 2217f49 commit 42c295a

File tree

6 files changed

+33
-20
lines changed

6 files changed

+33
-20
lines changed

.travis.yml

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,8 @@ after_success:
6464
- cmake -H. -Bbuild/coverage -DCMAKE_BUILD_TYPE=Debug -DLARS_EVENT_ENABLE_TESTS=On -DENABLE_TEST_COVERAGE=On -DCMAKE_CXX_COMPILER=g++-8
6565
- cmake --build build/coverage
6666
- cmake --build build/coverage --target test
67-
# collect coverage data
68-
- lcov --gcov-tool $(which gcov-8) --directory . --capture --output-file coverage.info
69-
# remove lib files
70-
- lcov --gcov-tool $(which gcov-8) --remove coverage.info '/usr/*' "${HOME}"'/.cache/*' --output-file coverage.info
71-
# remove test files
72-
- lcov --gcov-tool $(which gcov-8) --remove coverage.info $(pwd)/tests/*.cpp --output-file coverage.info
73-
# print coverage info
67+
# create coverage report
68+
- lcov --gcov-tool $(which gcov-8) --directory . --capture --no-external --exclude "*tests*" --exclude "*_deps*" --quiet --output-file coverage.info
69+
# output coverage
7470
- lcov --gcov-tool $(which gcov-8) --list coverage.info
75-
# upload coverage data
7671
- bash <(curl -s https://codecov.io/bash) -f coverage.info || echo "Codecov did not collect coverage reports"

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
33
# ---- Project ----
44

55
project(LarsEvent
6-
VERSION 2.0.2
6+
VERSION 2.0.3
77
LANGUAGES CXX
88
)
99

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ With [CPM](https://github.com/TheLartians/CPM), lars::Event can be used in a CMa
3636
```cmake
3737
CPMAddPackage(
3838
NAME LarsEvent
39-
VERSION 2.0.2
39+
VERSION 2.0.3
4040
GIT_REPOSITORY https://github.com/TheLartians/Event.git
4141
)
4242

include/lars/event.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <vector>
66
#include <utility>
77
#include <mutex>
8+
#include <algorithm>
89

910
namespace lars{
1011

@@ -45,7 +46,7 @@ namespace lars{
4546

4647
struct StoredHandler {
4748
HandlerID id;
48-
Handler callback;
49+
std::shared_ptr<Handler> callback;
4950
};
5051

5152
using HandlerList = std::vector<StoredHandler>;
@@ -60,7 +61,7 @@ namespace lars{
6061

6162
HandlerID addHandler(Handler h)const{
6263
std::lock_guard<std::mutex> lock(data->observerMutex);
63-
data->observers.emplace_back(StoredHandler{data->IDCounter,h});
64+
data->observers.emplace_back(StoredHandler{data->IDCounter,std::make_shared<Handler>(h)});
6465
return data->IDCounter++;
6566
}
6667

@@ -108,11 +109,17 @@ namespace lars{
108109
}
109110

110111
void emit(Args ... args) const {
112+
std::vector<std::weak_ptr<Handler>> handlers;
113+
handlers.resize(data->observers.size());
111114
data->observerMutex.lock();
112-
auto tmpObservers = data->observers;
115+
std::transform(data->observers.begin(), data->observers.end(), handlers.begin(), [](auto &h){
116+
return h.callback;
117+
});
113118
data->observerMutex.unlock();
114-
for(auto &observer: tmpObservers){
115-
observer.callback(args...);
119+
for(auto &weakCallback: handlers){
120+
if(auto callback = weakCallback.lock()){
121+
(*callback)(args...);
122+
}
116123
}
117124
}
118125

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ set_target_properties(lars-event-tests PROPERTIES CXX_STANDARD 17 COMPILE_FLAGS
3131

3232
ENABLE_TESTING()
3333
ADD_TEST(lars-event-tests lars-event-tests)
34+
3435
# ---- code coverage ----
3536

3637
if (${ENABLE_TEST_COVERAGE})

tests/event.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,21 @@ TEST_CASE("Event"){
5959
lars::Event<> event;
6060
lars::Event<>::Observer observer;
6161
unsigned count = 0;
62-
observer = event.createObserver([&](){ observer.reset(); count++; });
63-
event.emit();
64-
REQUIRE(count == 1);
65-
event.emit();
66-
REQUIRE(count == 1);
62+
SECTION("self removing"){
63+
observer = event.createObserver([&](){ observer.reset(); count++; });
64+
event.emit();
65+
REQUIRE(count == 1);
66+
event.emit();
67+
REQUIRE(count == 1);
68+
}
69+
SECTION("other removing"){
70+
event.connect([&](){ observer.reset(); });
71+
observer = event.createObserver([&](){ count++; });
72+
event.emit();
73+
REQUIRE(count == 0);
74+
event.emit();
75+
REQUIRE(count == 0);
76+
}
6777
}
6878

6979
SECTION("adding observers during emit"){

0 commit comments

Comments
 (0)