Home | History | Annotate | Download | only in bindings
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_PTR_SET_H_
      6 #define MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_PTR_SET_H_
      7 
      8 #include <utility>
      9 #include <vector>
     10 
     11 #include "base/macros.h"
     12 #include "base/memory/weak_ptr.h"
     13 #include "mojo/public/cpp/bindings/associated_interface_ptr.h"
     14 #include "mojo/public/cpp/bindings/interface_ptr.h"
     15 
     16 namespace mojo {
     17 namespace internal {
     18 
     19 template <typename Interface, template <typename> class Ptr>
     20 class PtrSet {
     21  public:
     22   PtrSet() {}
     23   ~PtrSet() { CloseAll(); }
     24 
     25   void AddPtr(Ptr<Interface> ptr) {
     26     auto weak_interface_ptr = new Element(std::move(ptr));
     27     ptrs_.push_back(weak_interface_ptr->GetWeakPtr());
     28     ClearNullPtrs();
     29   }
     30 
     31   template <typename FunctionType>
     32   void ForAllPtrs(FunctionType function) {
     33     for (const auto& it : ptrs_) {
     34       if (it)
     35         function(it->get());
     36     }
     37     ClearNullPtrs();
     38   }
     39 
     40   void CloseAll() {
     41     for (const auto& it : ptrs_) {
     42       if (it)
     43         it->Close();
     44     }
     45     ptrs_.clear();
     46   }
     47 
     48  private:
     49   class Element {
     50    public:
     51     explicit Element(Ptr<Interface> ptr)
     52         : ptr_(std::move(ptr)), weak_ptr_factory_(this) {
     53       ptr_.set_connection_error_handler(base::Bind(&DeleteElement, this));
     54     }
     55 
     56     ~Element() {}
     57 
     58     void Close() { ptr_.reset(); }
     59 
     60     Interface* get() { return ptr_.get(); }
     61 
     62     base::WeakPtr<Element> GetWeakPtr() {
     63       return weak_ptr_factory_.GetWeakPtr();
     64     }
     65 
     66    private:
     67     static void DeleteElement(Element* element) { delete element; }
     68 
     69     Ptr<Interface> ptr_;
     70     base::WeakPtrFactory<Element> weak_ptr_factory_;
     71 
     72     DISALLOW_COPY_AND_ASSIGN(Element);
     73   };
     74 
     75   void ClearNullPtrs() {
     76     ptrs_.erase(std::remove_if(ptrs_.begin(), ptrs_.end(),
     77                                [](const base::WeakPtr<Element>& p) {
     78                                  return p.get() == nullptr;
     79                                }),
     80                 ptrs_.end());
     81   }
     82 
     83   std::vector<base::WeakPtr<Element>> ptrs_;
     84 };
     85 
     86 }  // namespace internal
     87 
     88 template <typename Interface>
     89 using InterfacePtrSet = internal::PtrSet<Interface, InterfacePtr>;
     90 
     91 template <typename Interface>
     92 using AssociatedInterfacePtrSet =
     93     internal::PtrSet<Interface, AssociatedInterfacePtr>;
     94 
     95 }  // namespace mojo
     96 
     97 #endif  // MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_PTR_SET_H_
     98