Skip to content

Commit

Permalink
feat: Create ListenerManager to safely unregister listeners
Browse files Browse the repository at this point in the history
  • Loading branch information
mrousavy committed Feb 24, 2024
1 parent da82108 commit d7a2afb
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 16 deletions.
11 changes: 5 additions & 6 deletions package/cpp/Choreographer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//

#include "Choreographer.h"
#include "ListenerManager.h"

namespace margelo {

Expand All @@ -13,15 +14,13 @@ void Choreographer::loadHybridMethods() {
}

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

void Choreographer::onFrame(double timestamp) {
for (const auto& callback : _callbacks) {
callback(timestamp);
for (const auto& listener : _listeners.getListeners()) {
listener(timestamp);
}
}

Expand Down
3 changes: 2 additions & 1 deletion package/cpp/Choreographer.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#pragma once

#include "Listener.h"
#include "ListenerManager.h"
#include "jsi/HybridObject.h"
#include <functional>

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

private:
std::vector<OnFrameCallback> _callbacks;
ListenerManager<OnFrameCallback> _listeners;
};

} // namespace margelo
30 changes: 30 additions & 0 deletions package/cpp/ListenerManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// Created by Marc Rousavy on 24.02.24.
//

#pragma once

#include "Listener.h"
#include <algorithm>
#include <functional>
#include <list>

namespace margelo {

template <typename Callback> class ListenerManager {
private:
std::list<Callback> _listeners;

public:
Listener add(Callback listener) {
_listeners.push_back(std::move(listener));
auto id = --_listeners.end();
return Listener([id, this]() { _listeners.erase(id); });
}

const std::list<Callback>& getListeners() {
return _listeners;
}
};

} // namespace margelo
13 changes: 5 additions & 8 deletions package/cpp/SurfaceProvider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,29 @@ void SurfaceProvider::loadHybridMethods() {
registerHybridMethod("getSurface", &SurfaceProvider::getSurfaceOrNull, this);
}

Listener SurfaceProvider::addOnSurfaceChangedListener(margelo::SurfaceProvider::Callback callback) {
Listener SurfaceProvider::addOnSurfaceChangedListener(SurfaceProvider::Callback callback) {
std::unique_lock lock(_mutex);

_callbacks.push_back(std::move(callback));
return Listener([]() {
// TODO: Find a safe way to remove this listener from the vector.
});
return _listeners.add(std::move(callback));
}

void SurfaceProvider::onSurfaceCreated(std::shared_ptr<Surface> surface) {
std::unique_lock lock(_mutex);
for (const auto& listener : _callbacks) {
for (const auto& listener : _listeners.getListeners()) {
listener.onSurfaceCreated(surface);
}
}

void SurfaceProvider::onSurfaceChanged(std::shared_ptr<Surface> surface, int width, int height) {
std::unique_lock lock(_mutex);
for (const auto& listener : _callbacks) {
for (const auto& listener : _listeners.getListeners()) {
listener.onSurfaceSizeChanged(surface, width, height);
}
}

void SurfaceProvider::onSurfaceDestroyed(std::shared_ptr<Surface> surface) {
std::unique_lock lock(_mutex);
for (const auto& listener : _callbacks) {
for (const auto& listener : _listeners.getListeners()) {
listener.onSurfaceDestroyed(surface);
}
}
Expand Down
3 changes: 2 additions & 1 deletion package/cpp/SurfaceProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#pragma once

#include "Listener.h"
#include "ListenerManager.h"
#include "Surface.h"
#include "jsi/HybridObject.h"
#include <functional>
Expand Down Expand Up @@ -39,7 +40,7 @@ class SurfaceProvider : public HybridObject {
void onSurfaceDestroyed(std::shared_ptr<Surface> surface);

private:
std::vector<Callback> _callbacks;
ListenerManager<Callback> _listeners;
std::mutex _mutex;
};

Expand Down

0 comments on commit d7a2afb

Please sign in to comment.