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
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef mozilla_jni_GeckoResultUtils_h
8 #define mozilla_jni_GeckoResultUtils_h
9 
10 #include "mozilla/java/GeckoResultNatives.h"
11 #include "mozilla/jni/Conversions.h"
12 
13 namespace mozilla {
14 namespace jni {
15 
16 // C++-side object bound to Java's GeckoResult.GeckoCallback.
17 //
18 // Note that we can't template this class because that breaks JNI dispatch
19 // (surprisingly: it compiles, but selects the wrong method specialization
20 // during dispatch). So instead we use a templated factory function, which
21 // bundles the per-ArgType conversion logic into the callback.
22 class GeckoResultCallback final
23     : public java::GeckoResult::GeckoCallback::Natives<GeckoResultCallback> {
24  public:
25   typedef java::GeckoResult::GeckoCallback::Natives<GeckoResultCallback> Base;
26   typedef std::function<void(mozilla::jni::Object::Param)> OuterCallback;
27 
Call(mozilla::jni::Object::Param aArg)28   void Call(mozilla::jni::Object::Param aArg) { mCallback(aArg); }
29 
30   template <typename ArgType>
CreateAndAttach(std::function<void (ArgType)> && aInnerCallback)31   static java::GeckoResult::GeckoCallback::LocalRef CreateAndAttach(
32       std::function<void(ArgType)>&& aInnerCallback) {
33     auto java = java::GeckoResult::GeckoCallback::New();
34     OuterCallback outerCallback =
35         [inner{std::move(aInnerCallback)}](mozilla::jni::Object::Param aParam) {
36           ArgType converted = Java2Native<ArgType>(aParam);
37           inner(converted);
38         };
39     auto native = MakeUnique<GeckoResultCallback>(std::move(outerCallback));
40     Base::AttachNative(java, std::move(native));
41     return java;
42   }
43 
GeckoResultCallback(OuterCallback && aCallback)44   explicit GeckoResultCallback(OuterCallback&& aCallback)
45       : mCallback(std::move(aCallback)) {}
46 
47  private:
48   OuterCallback mCallback;
49 };
50 
51 }  // namespace jni
52 }  // namespace mozilla
53 
54 #endif  // mozilla_jni_GeckoResultUtils_h
55