// Generated by the announcer.rb  DO NOT EDIT!!

#import "SCManagedCapturerListenerAnnouncer.h"

#include <mutex>
using std::lock_guard;
using std::mutex;
#include <vector>
using std::find;
using std::make_shared;
using std::shared_ptr;
using std::vector;

@implementation SCManagedCapturerListenerAnnouncer {
    mutex _mutex;
    shared_ptr<vector<__weak id<SCManagedCapturerListener>>> _listeners;
}

- (NSString *)description
{
    auto listeners = atomic_load(&self->_listeners);
    NSMutableString *desc = [NSMutableString string];
    [desc appendFormat:@"<SCManagedCapturerListenerAnnouncer %p>: [", self];
    for (int i = 0; i < listeners->size(); ++i) {
        [desc appendFormat:@"%@", (*listeners)[i]];
        if (i != listeners->size() - 1) {
            [desc appendString:@", "];
        }
    }
    [desc appendString:@"]"];
    return desc;
}

- (BOOL)addListener:(id<SCManagedCapturerListener>)listener
{
    lock_guard<mutex> lock(_mutex);
    auto listeners = make_shared<vector<__weak id<SCManagedCapturerListener>>>();
    if (_listeners != nil) {
        // The listener we want to add already exists
        if (find(_listeners->begin(), _listeners->end(), listener) != _listeners->end()) {
            return NO;
        }
        for (auto &one : *_listeners) {
            if (one != nil) {
                listeners->push_back(one);
            }
        }
        listeners->push_back(listener);
        atomic_store(&self->_listeners, listeners);
    } else {
        listeners->push_back(listener);
        atomic_store(&self->_listeners, listeners);
    }
    return YES;
}

- (void)removeListener:(id<SCManagedCapturerListener>)listener
{
    lock_guard<mutex> lock(_mutex);
    if (_listeners == nil) {
        return;
    }
    // If the only item in the listener list is the one we want to remove, store it back to nil again
    if (_listeners->size() == 1 && (*_listeners)[0] == listener) {
        atomic_store(&self->_listeners, shared_ptr<vector<__weak id<SCManagedCapturerListener>>>());
        return;
    }
    auto listeners = make_shared<vector<__weak id<SCManagedCapturerListener>>>();
    for (auto &one : *_listeners) {
        if (one != nil && one != listener) {
            listeners->push_back(one);
        }
    }
    atomic_store(&self->_listeners, listeners);
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer didStartRunning:(SCManagedCapturerState *)state
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didStartRunning:)]) {
                [listener managedCapturer:managedCapturer didStartRunning:state];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer didStopRunning:(SCManagedCapturerState *)state
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didStopRunning:)]) {
                [listener managedCapturer:managedCapturer didStopRunning:state];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer didResetFromRuntimeError:(SCManagedCapturerState *)state
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didResetFromRuntimeError:)]) {
                [listener managedCapturer:managedCapturer didResetFromRuntimeError:state];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer didChangeState:(SCManagedCapturerState *)state
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didChangeState:)]) {
                [listener managedCapturer:managedCapturer didChangeState:state];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer didChangeNightModeActive:(SCManagedCapturerState *)state
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didChangeNightModeActive:)]) {
                [listener managedCapturer:managedCapturer didChangeNightModeActive:state];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer didChangePortraitModeActive:(SCManagedCapturerState *)state
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didChangePortraitModeActive:)]) {
                [listener managedCapturer:managedCapturer didChangePortraitModeActive:state];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer didChangeFlashActive:(SCManagedCapturerState *)state
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didChangeFlashActive:)]) {
                [listener managedCapturer:managedCapturer didChangeFlashActive:state];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer didChangeLensesActive:(SCManagedCapturerState *)state
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didChangeLensesActive:)]) {
                [listener managedCapturer:managedCapturer didChangeLensesActive:state];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer didChangeARSessionActive:(SCManagedCapturerState *)state
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didChangeARSessionActive:)]) {
                [listener managedCapturer:managedCapturer didChangeARSessionActive:state];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer
    didChangeFlashSupportedAndTorchSupported:(SCManagedCapturerState *)state
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didChangeFlashSupportedAndTorchSupported:)]) {
                [listener managedCapturer:managedCapturer didChangeFlashSupportedAndTorchSupported:state];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer didChangeZoomFactor:(SCManagedCapturerState *)state
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didChangeZoomFactor:)]) {
                [listener managedCapturer:managedCapturer didChangeZoomFactor:state];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer didChangeLowLightCondition:(SCManagedCapturerState *)state
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didChangeLowLightCondition:)]) {
                [listener managedCapturer:managedCapturer didChangeLowLightCondition:state];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer didChangeAdjustingExposure:(SCManagedCapturerState *)state
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didChangeAdjustingExposure:)]) {
                [listener managedCapturer:managedCapturer didChangeAdjustingExposure:state];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer didChangeCaptureDevicePosition:(SCManagedCapturerState *)state
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didChangeCaptureDevicePosition:)]) {
                [listener managedCapturer:managedCapturer didChangeCaptureDevicePosition:state];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer
    didChangeVideoPreviewLayer:(AVCaptureVideoPreviewLayer *)videoPreviewLayer
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didChangeVideoPreviewLayer:)]) {
                [listener managedCapturer:managedCapturer didChangeVideoPreviewLayer:videoPreviewLayer];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer didChangeVideoPreviewGLView:(LSAGLView *)videoPreviewGLView
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didChangeVideoPreviewGLView:)]) {
                [listener managedCapturer:managedCapturer didChangeVideoPreviewGLView:videoPreviewGLView];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer
 didBeginVideoRecording:(SCManagedCapturerState *)state
                session:(SCVideoCaptureSessionInfo)session
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didBeginVideoRecording:session:)]) {
                [listener managedCapturer:managedCapturer didBeginVideoRecording:state session:session];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer
 didBeginAudioRecording:(SCManagedCapturerState *)state
                session:(SCVideoCaptureSessionInfo)session
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didBeginAudioRecording:session:)]) {
                [listener managedCapturer:managedCapturer didBeginAudioRecording:state session:session];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer
    willFinishRecording:(SCManagedCapturerState *)state
                session:(SCVideoCaptureSessionInfo)session
    recordedVideoFuture:(SCFuture<id<SCManagedRecordedVideo>> *)recordedVideoFuture
              videoSize:(CGSize)videoSize
       placeholderImage:(UIImage *)placeholderImage
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:
                                                   willFinishRecording:
                                                               session:
                                                   recordedVideoFuture:
                                                             videoSize:
                                                      placeholderImage:)]) {
                [listener managedCapturer:managedCapturer
                      willFinishRecording:state
                                  session:session
                      recordedVideoFuture:recordedVideoFuture
                                videoSize:videoSize
                         placeholderImage:placeholderImage];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer
     didFinishRecording:(SCManagedCapturerState *)state
                session:(SCVideoCaptureSessionInfo)session
          recordedVideo:(SCManagedRecordedVideo *)recordedVideo
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didFinishRecording:session:recordedVideo:)]) {
                [listener managedCapturer:managedCapturer
                       didFinishRecording:state
                                  session:session
                            recordedVideo:recordedVideo];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer
       didFailRecording:(SCManagedCapturerState *)state
                session:(SCVideoCaptureSessionInfo)session
                  error:(NSError *)error
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didFailRecording:session:error:)]) {
                [listener managedCapturer:managedCapturer didFailRecording:state session:session error:error];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer
     didCancelRecording:(SCManagedCapturerState *)state
                session:(SCVideoCaptureSessionInfo)session
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didCancelRecording:session:)]) {
                [listener managedCapturer:managedCapturer didCancelRecording:state session:session];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer
            didGetError:(NSError *)error
                forType:(SCManagedVideoCapturerInfoType)type
                session:(SCVideoCaptureSessionInfo)session
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didGetError:forType:session:)]) {
                [listener managedCapturer:managedCapturer didGetError:error forType:type session:session];
            }
        }
    }
}

- (void)managedCapturerDidCallLenseResume:(id<SCCapturer>)managedCapturer session:(SCVideoCaptureSessionInfo)session
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturerDidCallLenseResume:session:)]) {
                [listener managedCapturerDidCallLenseResume:managedCapturer session:session];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer
    didAppendVideoSampleBuffer:(CMSampleBufferRef)sampleBuffer
                sampleMetadata:(SCManagedCapturerSampleMetadata *)sampleMetadata
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didAppendVideoSampleBuffer:sampleMetadata:)]) {
                [listener managedCapturer:managedCapturer
                    didAppendVideoSampleBuffer:sampleBuffer
                                sampleMetadata:sampleMetadata];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer
       willCapturePhoto:(SCManagedCapturerState *)state
         sampleMetadata:(SCManagedCapturerSampleMetadata *)sampleMetadata
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:willCapturePhoto:sampleMetadata:)]) {
                [listener managedCapturer:managedCapturer willCapturePhoto:state sampleMetadata:sampleMetadata];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer didCapturePhoto:(SCManagedCapturerState *)state
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didCapturePhoto:)]) {
                [listener managedCapturer:managedCapturer didCapturePhoto:state];
            }
        }
    }
}

- (BOOL)managedCapturer:(id<SCCapturer>)managedCapturer isUnderDeviceMotion:(SCManagedCapturerState *)state
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didCapturePhoto:)]) {
                return [listener managedCapturer:managedCapturer isUnderDeviceMotion:state];
            }
        }
    }
    return NO;
}

- (BOOL)managedCapturer:(id<SCCapturer>)managedCapturer shouldProcessFileInput:(SCManagedCapturerState *)state
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didCapturePhoto:)]) {
                return [listener managedCapturer:managedCapturer isUnderDeviceMotion:state];
            }
        }
    }
    return NO;
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer
    didDetectFaceBounds:(NSDictionary<NSNumber *, NSValue *> *)faceBoundsByFaceID
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didDetectFaceBounds:)]) {
                [listener managedCapturer:managedCapturer didDetectFaceBounds:faceBoundsByFaceID];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer didChangeExposurePoint:(CGPoint)exposurePoint
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didChangeExposurePoint:)]) {
                [listener managedCapturer:managedCapturer didChangeExposurePoint:exposurePoint];
            }
        }
    }
}

- (void)managedCapturer:(id<SCCapturer>)managedCapturer didChangeFocusPoint:(CGPoint)focusPoint
{
    auto listeners = atomic_load(&self->_listeners);
    if (listeners) {
        for (id<SCManagedCapturerListener> listener : *listeners) {
            if ([listener respondsToSelector:@selector(managedCapturer:didChangeFocusPoint:)]) {
                [listener managedCapturer:managedCapturer didChangeFocusPoint:focusPoint];
            }
        }
    }
}

@end