1 // Copyright 2019 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 THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SETLIKE_H_
6 #define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SETLIKE_H_
7 
8 #include "third_party/blink/renderer/bindings/core/v8/iterable.h"
9 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
10 
11 namespace blink {
12 
13 // Utility class to simplify implementation of various `setlike` classes.
14 // The consumer of the class needs only to implement the |elements()| method -
15 // everything else should be provided by this class. For examples, see
16 // `XRPlaneSet` and `XRAnchorSet`.
17 template <typename ElementType>
18 class XRSetlike : public SetlikeIterable<Member<ElementType>> {
19  public:
size()20   unsigned size() const { return elements().size(); }
21 
22   // Returns true if passed in |element| is a member of the XRSetlike.
hasForBinding(ScriptState * script_state,ElementType * element,ExceptionState & exception_state)23   bool hasForBinding(ScriptState* script_state,
24                      ElementType* element,
25                      ExceptionState& exception_state) const {
26     DCHECK(element);
27     auto all_elements = elements();
28     return all_elements.find(element) != all_elements.end();
29   }
30 
31  protected:
32   virtual const HeapHashSet<Member<ElementType>>& elements() const = 0;
33 
34  private:
35   class IterationSource final
36       : public SetlikeIterable<Member<ElementType>>::IterationSource {
37    public:
IterationSource(const HeapHashSet<Member<ElementType>> & elements)38     explicit IterationSource(const HeapHashSet<Member<ElementType>>& elements)
39         : index_(0) {
40       elements_.ReserveInitialCapacity(elements.size());
41       for (auto element : elements) {
42         elements_.push_back(element);
43       }
44     }
45 
Next(ScriptState * script_state,Member<ElementType> & key,Member<ElementType> & value,ExceptionState & exception_state)46     bool Next(ScriptState* script_state,
47               Member<ElementType>& key,
48               Member<ElementType>& value,
49               ExceptionState& exception_state) override {
50       if (index_ >= elements_.size()) {
51         return false;
52       }
53 
54       key = value = elements_[index_];
55       ++index_;
56 
57       return true;
58     }
59 
Trace(Visitor * visitor)60     void Trace(Visitor* visitor) const override {
61       visitor->Trace(elements_);
62       SetlikeIterable<Member<ElementType>>::IterationSource::Trace(visitor);
63     }
64 
65    private:
66     HeapVector<Member<ElementType>> elements_;
67 
68     unsigned index_;
69   };
70 
71   // Starts iteration over XRSetlike.
72   // Needed for SetlikeIterable to work properly.
StartIteration(ScriptState * script_state,ExceptionState & exception_state)73   XRSetlike::IterationSource* StartIteration(
74       ScriptState* script_state,
75       ExceptionState& exception_state) override {
76     return MakeGarbageCollected<XRSetlike::IterationSource>(elements());
77   }
78 };
79 
80 }  // namespace blink
81 
82 #endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SETLIKE_H_
83