diff options
Diffstat (limited to 'layout/xul/nsRepeatService.cpp')
-rw-r--r-- | layout/xul/nsRepeatService.cpp | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/layout/xul/nsRepeatService.cpp b/layout/xul/nsRepeatService.cpp new file mode 100644 index 0000000000..5495a0a10f --- /dev/null +++ b/layout/xul/nsRepeatService.cpp @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// +// Eric Vaughan +// Netscape Communications +// +// See documentation in associated header file +// + +#include "nsRepeatService.h" +#include "mozilla/StaticPtr.h" +#include "mozilla/dom/Document.h" + +using namespace mozilla; + +static StaticAutoPtr<nsRepeatService> gRepeatService; + +nsRepeatService::nsRepeatService() + : mCallback(nullptr), mCallbackData(nullptr) {} + +nsRepeatService::~nsRepeatService() { + NS_ASSERTION(!mCallback && !mCallbackData, + "Callback was not removed before shutdown"); +} + +/* static */ +nsRepeatService* nsRepeatService::GetInstance() { + if (!gRepeatService) { + gRepeatService = new nsRepeatService(); + } + return gRepeatService; +} + +/*static*/ +void nsRepeatService::Shutdown() { gRepeatService = nullptr; } + +void nsRepeatService::Start(Callback aCallback, void* aCallbackData, + dom::Document* aDocument, + const nsACString& aCallbackName, + uint32_t aInitialDelay) { + MOZ_ASSERT(aCallback != nullptr, "null ptr"); + + mCallback = aCallback; + mCallbackData = aCallbackData; + mCallbackName = aCallbackName; + + mRepeatTimer = NS_NewTimer(GetMainThreadSerialEventTarget()); + + if (mRepeatTimer) { + InitTimerCallback(aInitialDelay); + } +} + +void nsRepeatService::Stop(Callback aCallback, void* aCallbackData) { + if (mCallback != aCallback || mCallbackData != aCallbackData) return; + + // printf("Stopping repeat timer\n"); + if (mRepeatTimer) { + mRepeatTimer->Cancel(); + mRepeatTimer = nullptr; + } + mCallback = nullptr; + mCallbackData = nullptr; +} + +void nsRepeatService::InitTimerCallback(uint32_t aInitialDelay) { + if (!mRepeatTimer) { + return; + } + + mRepeatTimer->InitWithNamedFuncCallback( + [](nsITimer* aTimer, void* aClosure) { + // Use gRepeatService instead of nsRepeatService::GetInstance() (because + // we don't want nsRepeatService::GetInstance() to re-create a new + // instance for us, if we happen to get invoked after + // nsRepeatService::Shutdown() has nulled out gRepeatService). + nsRepeatService* rs = gRepeatService; + if (!rs) { + return; + } + + if (rs->mCallback) { + rs->mCallback(rs->mCallbackData); + } + + rs->InitTimerCallback(REPEAT_DELAY); + }, + nullptr, aInitialDelay, nsITimer::TYPE_ONE_SHOT, mCallbackName.Data()); +} |