/*
 * Copyright 2020 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkIDChangeListener_DEFINED
#define SkIDChangeListener_DEFINED

#include "include/core/SkRefCnt.h"
#include "include/private/SkMutex.h"
#include "include/private/SkTArray.h"

#include <atomic>

/**
 * Used to be notified when a gen/unique ID is invalidated, typically to preemptively purge
 * associated items from a cache that are no longer reachable. The listener can
 * be marked for deregistration if the cached item is remove before the listener is
 * triggered. This prevents unbounded listener growth when cache items are routinely
 * removed before the gen ID/unique ID is invalidated.
 */
class SkIDChangeListener : public SkRefCnt {
public:
    SkIDChangeListener();

    ~SkIDChangeListener() override;

    virtual void changed() = 0;

    /**
     * Mark the listener is no longer needed. It should be removed and changed() should not be
     * called.
     */
    void markShouldDeregister() { fShouldDeregister.store(true, std::memory_order_relaxed); }

    /** Indicates whether markShouldDeregister was called. */
    bool shouldDeregister() { return fShouldDeregister.load(std::memory_order_acquire); }

    /** Manages a list of SkIDChangeListeners. */
    class List {
    public:
        List();

        ~List();

        /**
         * Add a new listener to the list. It must not already be deregistered. Also clears out
         * previously deregistered listeners.
         */
        void add(sk_sp<SkIDChangeListener> listener) SK_EXCLUDES(fMutex);

        /**
         * The number of registered listeners (including deregisterd listeners that are yet-to-be
         * removed.
         */
        int count() const SK_EXCLUDES(fMutex);

        /** Calls changed() on all listeners that haven't been deregistered and resets the list. */
        void changed() SK_EXCLUDES(fMutex);

        /** Resets without calling changed() on the listeners. */
        void reset() SK_EXCLUDES(fMutex);

    private:
        mutable SkMutex fMutex;
        SkSTArray<1, sk_sp<SkIDChangeListener>> fListeners SK_GUARDED_BY(fMutex);
    };

private:
    std::atomic<bool> fShouldDeregister;
};

#endif
