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_widget_WindowEvent_h
8 #define mozilla_widget_WindowEvent_h
9 
10 #include "nsThreadUtils.h"
11 #include "mozilla/jni/Natives.h"
12 
13 namespace mozilla {
14 namespace widget {
15 
16 // An Event subclass that guards against stale events.
17 // (See the implmentation of mozilla::jni::detail::ProxyNativeCall for info
18 //  about the default template parameters for this class)
19 template <typename Lambda, bool IsStatic = Lambda::isStatic,
20           typename InstanceType = typename Lambda::ThisArgType,
21           class Impl = typename Lambda::TargetClass>
22 class WindowEvent : public Runnable {
IsStaleCall()23   bool IsStaleCall() {
24     if (IsStatic) {
25       // Static calls are never stale.
26       return false;
27     }
28 
29     return jni::NativePtrTraits<Impl>::IsStale(mInstance);
30   }
31 
32   Lambda mLambda;
33   const InstanceType mInstance;
34 
35  public:
WindowEvent(Lambda && aLambda,InstanceType && aInstance)36   WindowEvent(Lambda&& aLambda, InstanceType&& aInstance)
37       : Runnable("mozilla::widget::WindowEvent"),
38         mLambda(std::move(aLambda)),
39         mInstance(std::forward<InstanceType>(aInstance)) {}
40 
WindowEvent(Lambda && aLambda)41   explicit WindowEvent(Lambda&& aLambda)
42       : Runnable("mozilla::widget::WindowEvent"),
43         mLambda(std::move(aLambda)),
44         mInstance(mLambda.GetThisArg()) {}
45 
Run()46   NS_IMETHOD Run() override {
47     if (!IsStaleCall()) {
48       mLambda();
49     }
50     return NS_OK;
51   }
52 };
53 
54 }  // namespace widget
55 }  // namespace mozilla
56 
57 #endif  // mozilla_widget_WindowEvent_h
58