1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/TestInterfaceAsyncIterableSingle.h"
8 #include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
9 #include "nsPIDOMWindow.h"
10 #include "mozilla/dom/BindingUtils.h"
11 #include "mozilla/dom/IterableIterator.h"
12 #include "mozilla/dom/Promise-inl.h"
13 #include "nsThreadUtils.h"
15 namespace mozilla::dom
{
17 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TestInterfaceAsyncIterableSingle
, mParent
)
19 NS_IMPL_CYCLE_COLLECTING_ADDREF(TestInterfaceAsyncIterableSingle
)
20 NS_IMPL_CYCLE_COLLECTING_RELEASE(TestInterfaceAsyncIterableSingle
)
22 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TestInterfaceAsyncIterableSingle
)
23 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
24 NS_INTERFACE_MAP_ENTRY(nsISupports
)
27 TestInterfaceAsyncIterableSingle::TestInterfaceAsyncIterableSingle(
28 nsPIDOMWindowInner
* aParent
, bool aFailToInit
)
29 : mParent(aParent
), mFailToInit(aFailToInit
) {}
32 already_AddRefed
<TestInterfaceAsyncIterableSingle
>
33 TestInterfaceAsyncIterableSingle::Constructor(
34 const GlobalObject
& aGlobal
,
35 const TestInterfaceAsyncIterableSingleOptions
& aOptions
, ErrorResult
& aRv
) {
36 nsCOMPtr
<nsPIDOMWindowInner
> window
=
37 do_QueryInterface(aGlobal
.GetAsSupports());
39 aRv
.Throw(NS_ERROR_FAILURE
);
43 RefPtr
<TestInterfaceAsyncIterableSingle
> r
=
44 new TestInterfaceAsyncIterableSingle(window
, aOptions
.mFailToInit
);
48 JSObject
* TestInterfaceAsyncIterableSingle::WrapObject(
49 JSContext
* aCx
, JS::Handle
<JSObject
*> aGivenProto
) {
50 return TestInterfaceAsyncIterableSingle_Binding::Wrap(aCx
, this, aGivenProto
);
53 nsPIDOMWindowInner
* TestInterfaceAsyncIterableSingle::GetParentObject() const {
57 void TestInterfaceAsyncIterableSingle::InitAsyncIteratorData(
58 IteratorData
& aData
, Iterator::IteratorType aType
, ErrorResult
& aError
) {
60 aError
.ThrowTypeError("Caller asked us to fail");
64 // Nothing else to do.
65 MOZ_ASSERT(aData
.mIndex
== 0);
66 MOZ_ASSERT(aData
.mMultiplier
== 1);
69 already_AddRefed
<Promise
>
70 TestInterfaceAsyncIterableSingle::GetNextIterationResult(Iterator
* aIterator
,
72 return GetNextIterationResult(aIterator
, aIterator
->Data(), aRv
);
75 already_AddRefed
<Promise
>
76 TestInterfaceAsyncIterableSingle::GetNextIterationResult(
77 IterableIteratorBase
* aIterator
, IteratorData
& aData
, ErrorResult
& aRv
) {
78 RefPtr
<Promise
> promise
= Promise::Create(mParent
->AsGlobal(), aRv
);
79 if (NS_WARN_IF(aRv
.Failed())) {
83 nsCOMPtr
<nsIRunnable
> callResolvePromise
=
84 NewRunnableMethod
<RefPtr
<IterableIteratorBase
>, IteratorData
&,
86 "TestInterfaceAsyncIterableSingle::GetNextIterationResult", this,
87 &TestInterfaceAsyncIterableSingle::ResolvePromise
, aIterator
, aData
,
89 if (aData
.mBlockingPromisesIndex
< aData
.mBlockingPromises
.Length()) {
90 aData
.mBlockingPromises
[aData
.mBlockingPromisesIndex
]
91 ->AddCallbacksWithCycleCollectedArgs(
92 [](JSContext
* aCx
, JS::Handle
<JS::Value
> aValue
, ErrorResult
& aRv
,
93 nsIRunnable
* aCallResolvePromise
) {
94 NS_DispatchToMainThread(aCallResolvePromise
);
96 [](JSContext
* aCx
, JS::Handle
<JS::Value
> aValue
, ErrorResult
& aRv
,
97 nsIRunnable
* aCallResolvePromise
) {},
98 std::move(callResolvePromise
));
99 ++aData
.mBlockingPromisesIndex
;
101 NS_DispatchToMainThread(callResolvePromise
);
104 return promise
.forget();
107 void TestInterfaceAsyncIterableSingle::ResolvePromise(
108 IterableIteratorBase
* aIterator
, IteratorData
& aData
, Promise
* aPromise
) {
109 if (aData
.mIndex
>= 10) {
110 iterator_utils::ResolvePromiseForFinished(aPromise
);
112 aPromise
->MaybeResolve(int32_t(aData
.mIndex
* 9 % 7 * aData
.mMultiplier
));
118 void TestInterfaceAsyncIterableSingle::IteratorData::Traverse(
119 nsCycleCollectionTraversalCallback
& cb
) {
120 TestInterfaceAsyncIterableSingle::IteratorData
* tmp
= this;
121 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBlockingPromises
);
122 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mThrowFromReturn
);
124 void TestInterfaceAsyncIterableSingle::IteratorData::Unlink() {
125 TestInterfaceAsyncIterableSingle::IteratorData
* tmp
= this;
126 NS_IMPL_CYCLE_COLLECTION_UNLINK(mBlockingPromises
);
127 NS_IMPL_CYCLE_COLLECTION_UNLINK(mThrowFromReturn
);
130 } // namespace mozilla::dom