2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/system/common/timer-impl.h>
20 #include "extern-definitions.h"
22 namespace Dali::Internal::Adaptor
25 * Struct to hide away macOS implementation details
29 Impl(Timer* parent, unsigned int milliSec)
30 : mTimer(CreateTimer(parent, milliSec))
39 static void TimerProc(CFRunLoopTimerRef timer, void* info);
43 void Reset(Timer* parent, unsigned int milliSec);
45 unsigned int GetInterval() const noexcept
47 return CFRunLoopTimerGetInterval(mTimer.get()) * 1000.0;
50 bool IsRunning() const noexcept
52 return CFRunLoopTimerIsValid(mTimer.get());
56 CFRef<CFRunLoopTimerRef> CreateTimer(Timer* parent, unsigned int milliSec);
58 CFRef<CFRunLoopTimerRef> mTimer;
61 void Timer::Impl::TimerProc(CFRunLoopTimerRef timer, void* info)
63 auto* pTimer = static_cast<Timer*>(info);
67 void Timer::Impl::Start()
71 auto runLoop = CFRunLoopGetMain();
72 CFRunLoopAddTimer(runLoop, mTimer.get(), kCFRunLoopDefaultMode);
76 void Timer::Impl::Stop()
80 CFRunLoopTimerContext context;
81 CFRunLoopTimerGetContext(mTimer.get(), &context);
82 const auto interval = CFRunLoopTimerGetInterval(mTimer.get());
83 CFRunLoopTimerInvalidate(mTimer.get());
85 // After we invalidate the timer, we can't reuse it, so we create
86 // a new timer for case the user calls Start again
87 const auto fireDate = CFAbsoluteTimeGetCurrent() + interval;
88 mTimer.reset(CFRunLoopTimerCreate(
99 void Timer::Impl::Reset(Timer* parent, unsigned int milliSec)
102 mTimer = CreateTimer(parent, milliSec);
106 CFRef<CFRunLoopTimerRef>
107 Timer::Impl::CreateTimer(Timer* parent, unsigned int milliSec)
109 const auto interval = static_cast<CFAbsoluteTime>(milliSec) / 1000;
110 const auto fireDate = CFAbsoluteTimeGetCurrent() + interval;
111 CFRunLoopTimerContext context =
119 return MakeRef(CFRunLoopTimerCreate(
129 TimerPtr Timer::New(unsigned int milliSec)
131 return new Timer(milliSec);
134 Timer::Timer(unsigned int milliSec)
135 : mImpl(new Impl(this, milliSec))
166 void Timer::SetInterval(unsigned int interval, bool restart)
168 mImpl->Reset(this, interval);
171 unsigned int Timer::GetInterval() const
173 return mImpl->GetInterval();
178 // Guard against destruction during signal emission
179 Dali::Timer handle(this);
183 // Override with new signal if used
184 if(!mTickSignal.Empty())
186 retVal = mTickSignal.Emit();
188 // Timer stops if return value is false
195 retVal = true; // continue emission
198 else // no callbacks registered
200 // periodic timer is started but nobody listens, continue
207 Dali::Timer::TimerSignalType& Timer::TickSignal()
212 bool Timer::IsRunning() const
214 return mImpl->IsRunning();
217 } // namespace Dali::Internal::Adaptor