Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : //
7 : // Eric Vaughan
8 : // Netscape Communications
9 : //
10 : // See documentation in associated header file
11 : //
12 :
13 : #include "nsRepeatService.h"
14 : #include "mozilla/StaticPtr.h"
15 : #include "nsIDocument.h"
16 : #include "nsIServiceManager.h"
17 :
18 : using namespace mozilla;
19 :
20 3 : static StaticAutoPtr<nsRepeatService> gRepeatService;
21 :
22 0 : nsRepeatService::nsRepeatService()
23 0 : : mCallback(nullptr), mCallbackData(nullptr)
24 : {
25 0 : }
26 :
27 0 : nsRepeatService::~nsRepeatService()
28 : {
29 0 : NS_ASSERTION(!mCallback && !mCallbackData, "Callback was not removed before shutdown");
30 0 : }
31 :
32 : /* static */ nsRepeatService*
33 0 : nsRepeatService::GetInstance()
34 : {
35 0 : if (!gRepeatService) {
36 0 : gRepeatService = new nsRepeatService();
37 : }
38 0 : return gRepeatService;
39 : }
40 :
41 : /*static*/ void
42 0 : nsRepeatService::Shutdown()
43 : {
44 0 : gRepeatService = nullptr;
45 0 : }
46 :
47 : void
48 0 : nsRepeatService::Start(Callback aCallback, void* aCallbackData,
49 : nsIDocument* aDocument, const nsACString& aCallbackName,
50 : uint32_t aInitialDelay)
51 : {
52 0 : NS_PRECONDITION(aCallback != nullptr, "null ptr");
53 :
54 0 : mCallback = aCallback;
55 0 : mCallbackData = aCallbackData;
56 0 : mCallbackName = aCallbackName;
57 :
58 : nsresult rv;
59 0 : mRepeatTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
60 :
61 0 : if (NS_SUCCEEDED(rv)) {
62 0 : mRepeatTimer->SetTarget(aDocument->EventTargetFor(TaskCategory::Other));
63 0 : InitTimerCallback(aInitialDelay);
64 : }
65 0 : }
66 :
67 0 : void nsRepeatService::Stop(Callback aCallback, void* aCallbackData)
68 : {
69 0 : if (mCallback != aCallback || mCallbackData != aCallbackData)
70 0 : return;
71 :
72 : //printf("Stopping repeat timer\n");
73 0 : if (mRepeatTimer) {
74 0 : mRepeatTimer->Cancel();
75 0 : mRepeatTimer = nullptr;
76 : }
77 0 : mCallback = nullptr;
78 0 : mCallbackData = nullptr;
79 : }
80 :
81 : void
82 0 : nsRepeatService::InitTimerCallback(uint32_t aInitialDelay)
83 : {
84 0 : if (!mRepeatTimer) {
85 0 : return;
86 : }
87 :
88 0 : mRepeatTimer->InitWithNamedFuncCallback([](nsITimer* aTimer, void* aClosure) {
89 : // Use gRepeatService instead of nsRepeatService::GetInstance() (because
90 : // we don't want nsRepeatService::GetInstance() to re-create a new instance
91 : // for us, if we happen to get invoked after nsRepeatService::Shutdown() has
92 : // nulled out gRepeatService).
93 0 : nsRepeatService* rs = gRepeatService;
94 0 : if (!rs) {
95 0 : return;
96 : }
97 :
98 0 : if (rs->mCallback) {
99 0 : rs->mCallback(rs->mCallbackData);
100 : }
101 :
102 0 : rs->InitTimerCallback(REPEAT_DELAY);
103 0 : }, nullptr, aInitialDelay, nsITimer::TYPE_ONE_SHOT, mCallbackName.Data());
104 : }
|