Skip to content

Commit d7a2afb

Browse files
committed
feat: Create ListenerManager to safely unregister listeners
1 parent da82108 commit d7a2afb

File tree

5 files changed

+44
-16
lines changed

5 files changed

+44
-16
lines changed

package/cpp/Choreographer.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
//
44

55
#include "Choreographer.h"
6+
#include "ListenerManager.h"
67

78
namespace margelo {
89

@@ -13,15 +14,13 @@ void Choreographer::loadHybridMethods() {
1314
}
1415

1516
std::shared_ptr<Listener> Choreographer::addOnFrameListener(Choreographer::OnFrameCallback onFrameCallback) {
16-
_callbacks.push_back(std::move(onFrameCallback));
17-
return std::make_shared<Listener>([]() {
18-
// TODO: Find a safe way to remove this listener from the vector.
19-
});
17+
auto listener = _listeners.add(std::move(onFrameCallback));
18+
return std::make_shared<Listener>(std::move(listener));
2019
}
2120

2221
void Choreographer::onFrame(double timestamp) {
23-
for (const auto& callback : _callbacks) {
24-
callback(timestamp);
22+
for (const auto& listener : _listeners.getListeners()) {
23+
listener(timestamp);
2524
}
2625
}
2726

package/cpp/Choreographer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#pragma once
66

77
#include "Listener.h"
8+
#include "ListenerManager.h"
89
#include "jsi/HybridObject.h"
910
#include <functional>
1011

@@ -25,7 +26,7 @@ class Choreographer : public HybridObject {
2526
void loadHybridMethods() override;
2627

2728
private:
28-
std::vector<OnFrameCallback> _callbacks;
29+
ListenerManager<OnFrameCallback> _listeners;
2930
};
3031

3132
} // namespace margelo

package/cpp/ListenerManager.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//
2+
// Created by Marc Rousavy on 24.02.24.
3+
//
4+
5+
#pragma once
6+
7+
#include "Listener.h"
8+
#include <algorithm>
9+
#include <functional>
10+
#include <list>
11+
12+
namespace margelo {
13+
14+
template <typename Callback> class ListenerManager {
15+
private:
16+
std::list<Callback> _listeners;
17+
18+
public:
19+
Listener add(Callback listener) {
20+
_listeners.push_back(std::move(listener));
21+
auto id = --_listeners.end();
22+
return Listener([id, this]() { _listeners.erase(id); });
23+
}
24+
25+
const std::list<Callback>& getListeners() {
26+
return _listeners;
27+
}
28+
};
29+
30+
} // namespace margelo

package/cpp/SurfaceProvider.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,32 +10,29 @@ void SurfaceProvider::loadHybridMethods() {
1010
registerHybridMethod("getSurface", &SurfaceProvider::getSurfaceOrNull, this);
1111
}
1212

13-
Listener SurfaceProvider::addOnSurfaceChangedListener(margelo::SurfaceProvider::Callback callback) {
13+
Listener SurfaceProvider::addOnSurfaceChangedListener(SurfaceProvider::Callback callback) {
1414
std::unique_lock lock(_mutex);
1515

16-
_callbacks.push_back(std::move(callback));
17-
return Listener([]() {
18-
// TODO: Find a safe way to remove this listener from the vector.
19-
});
16+
return _listeners.add(std::move(callback));
2017
}
2118

2219
void SurfaceProvider::onSurfaceCreated(std::shared_ptr<Surface> surface) {
2320
std::unique_lock lock(_mutex);
24-
for (const auto& listener : _callbacks) {
21+
for (const auto& listener : _listeners.getListeners()) {
2522
listener.onSurfaceCreated(surface);
2623
}
2724
}
2825

2926
void SurfaceProvider::onSurfaceChanged(std::shared_ptr<Surface> surface, int width, int height) {
3027
std::unique_lock lock(_mutex);
31-
for (const auto& listener : _callbacks) {
28+
for (const auto& listener : _listeners.getListeners()) {
3229
listener.onSurfaceSizeChanged(surface, width, height);
3330
}
3431
}
3532

3633
void SurfaceProvider::onSurfaceDestroyed(std::shared_ptr<Surface> surface) {
3734
std::unique_lock lock(_mutex);
38-
for (const auto& listener : _callbacks) {
35+
for (const auto& listener : _listeners.getListeners()) {
3936
listener.onSurfaceDestroyed(surface);
4037
}
4138
}

package/cpp/SurfaceProvider.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#pragma once
66

77
#include "Listener.h"
8+
#include "ListenerManager.h"
89
#include "Surface.h"
910
#include "jsi/HybridObject.h"
1011
#include <functional>
@@ -39,7 +40,7 @@ class SurfaceProvider : public HybridObject {
3940
void onSurfaceDestroyed(std::shared_ptr<Surface> surface);
4041

4142
private:
42-
std::vector<Callback> _callbacks;
43+
ListenerManager<Callback> _listeners;
4344
std::mutex _mutex;
4445
};
4546

0 commit comments

Comments
 (0)