juce中timer总体说还是比较好用的,使用时只需继承timer类, 重写callback然后调用start就可以了,juce的timer比较特别,自己通过线程实现,starttimer的时候会创建一个timerthread,然后在这个timerthread的构造函数中又触发了triggerAsyncUpdate(); 这样异步使线程start, 这样做是为了让timer对象添登记以后才开始线程,这也是常用技法, 然后在线程中检查定时是否到达,如果到达了的话就post消息,然后回调,只是这时其实已经在消息线程中了

    struct CallTimersMessage  : public MessageManager::MessageBase
{
CallTimersMessage() {} void messageCallback() override
{
if (instance != nullptr)
instance->callTimers();
}
};

  instance->callTimers(); 再调用各个timer的callback,也就是你重写的处理函数,大体就分析到这里,下次再进行一次仔细分析,前提条件没有准备充分,仔细分析太耗费时间。

/*
============================================================================== This file is part of the JUCE library.
Copyright (c) 2015 - ROLI Ltd. Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3 Details of these licenses can be found at: www.gnu.org/licenses JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details. ------------------------------------------------------------------------------ To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information. ==============================================================================
*/ class Timer::TimerThread : private Thread,
private DeletedAtShutdown,
private AsyncUpdater
{
public:
typedef CriticalSection LockType; // (mysteriously, using a SpinLock here causes problems on some XP machines..) TimerThread()
: Thread ("Juce Timer"),
firstTimer (nullptr)
{
triggerAsyncUpdate();
} ~TimerThread() noexcept
{
signalThreadShouldExit();
callbackArrived.signal();
stopThread (4000); jassert (instance == this || instance == nullptr);
if (instance == this)
instance = nullptr;
} void run() override
{
uint32 lastTime = Time::getMillisecondCounter();
MessageManager::MessageBase::Ptr messageToSend (new CallTimersMessage()); while (! threadShouldExit())
{
const uint32 now = Time::getMillisecondCounter(); const int elapsed = (int) (now >= lastTime ? (now - lastTime)
: (std::numeric_limits<uint32>::max() - (lastTime - now)));
lastTime = now; const int timeUntilFirstTimer = getTimeUntilFirstTimer (elapsed); if (timeUntilFirstTimer <= 0)
{
if (callbackArrived.wait (0))
{
// already a message in flight - do nothing..
}
else
{
messageToSend->post(); if (! callbackArrived.wait (300))
{
// Sometimes our message can get discarded by the OS (e.g. when running as an RTAS
// when the app has a modal loop), so this is how long to wait before assuming the
// message has been lost and trying again.
messageToSend->post();
} continue;
}
} // don't wait for too long because running this loop also helps keep the
// Time::getApproximateMillisecondTimer value stay up-to-date
wait (jlimit (1, 100, timeUntilFirstTimer));
}
} void callTimers()
{
// avoid getting stuck in a loop if a timer callback repeatedly takes too long
const uint32 timeout = Time::getMillisecondCounter() + 100; const LockType::ScopedLockType sl (lock); while (firstTimer != nullptr && firstTimer->timerCountdownMs <= 0)
{
Timer* const t = firstTimer;
t->timerCountdownMs = t->timerPeriodMs; removeTimer (t);
addTimer (t); const LockType::ScopedUnlockType ul (lock); JUCE_TRY
{
t->timerCallback();
}
JUCE_CATCH_EXCEPTION if (Time::getMillisecondCounter() > timeout)
break;
} callbackArrived.signal();
} void callTimersSynchronously()
{
if (! isThreadRunning())
{
// (This is relied on by some plugins in cases where the MM has
// had to restart and the async callback never started)
cancelPendingUpdate();
triggerAsyncUpdate();
} callTimers();
} static inline void add (Timer* const tim) noexcept
{
if (instance == nullptr)
instance = new TimerThread(); instance->addTimer (tim);
} static inline void remove (Timer* const tim) noexcept
{
if (instance != nullptr)
instance->removeTimer (tim);
} static inline void resetCounter (Timer* const tim, const int newCounter) noexcept
{
if (instance != nullptr)
{
tim->timerCountdownMs = newCounter;
tim->timerPeriodMs = newCounter; if ((tim->nextTimer != nullptr && tim->nextTimer->timerCountdownMs < tim->timerCountdownMs)
|| (tim->previousTimer != nullptr && tim->previousTimer->timerCountdownMs > tim->timerCountdownMs))
{
instance->removeTimer (tim);
instance->addTimer (tim);
}
}
} static TimerThread* instance;
static LockType lock; private:
Timer* volatile firstTimer;
WaitableEvent callbackArrived; struct CallTimersMessage : public MessageManager::MessageBase
{
CallTimersMessage() {} void messageCallback() override
{
if (instance != nullptr)
instance->callTimers();
}
}; //==============================================================================
void addTimer (Timer* const t) noexcept
{
#if JUCE_DEBUG
// trying to add a timer that's already here - shouldn't get to this point,
// so if you get this assertion, let me know!
jassert (! timerExists (t));
#endif Timer* i = firstTimer; if (i == nullptr || i->timerCountdownMs > t->timerCountdownMs)
{
t->nextTimer = firstTimer;
firstTimer = t;
}
else
{
while (i->nextTimer != nullptr && i->nextTimer->timerCountdownMs <= t->timerCountdownMs)
i = i->nextTimer; jassert (i != nullptr); t->nextTimer = i->nextTimer;
t->previousTimer = i;
i->nextTimer = t;
} if (t->nextTimer != nullptr)
t->nextTimer->previousTimer = t; jassert ((t->nextTimer == nullptr || t->nextTimer->timerCountdownMs >= t->timerCountdownMs)
&& (t->previousTimer == nullptr || t->previousTimer->timerCountdownMs <= t->timerCountdownMs)); notify();
} void removeTimer (Timer* const t) noexcept
{
#if JUCE_DEBUG
// trying to remove a timer that's not here - shouldn't get to this point,
// so if you get this assertion, let me know!
jassert (timerExists (t));
#endif if (t->previousTimer != nullptr)
{
jassert (firstTimer != t);
t->previousTimer->nextTimer = t->nextTimer;
}
else
{
jassert (firstTimer == t);
firstTimer = t->nextTimer;
} if (t->nextTimer != nullptr)
t->nextTimer->previousTimer = t->previousTimer; t->nextTimer = nullptr;
t->previousTimer = nullptr;
} int getTimeUntilFirstTimer (const int numMillisecsElapsed) const
{
const LockType::ScopedLockType sl (lock); for (Timer* t = firstTimer; t != nullptr; t = t->nextTimer)
t->timerCountdownMs -= numMillisecsElapsed; return firstTimer != nullptr ? firstTimer->timerCountdownMs : 1000;
} void handleAsyncUpdate() override
{
startThread (7);
} #if JUCE_DEBUG
bool timerExists (Timer* const t) const noexcept
{
for (Timer* tt = firstTimer; tt != nullptr; tt = tt->nextTimer)
if (tt == t)
return true; return false;
}
#endif JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TimerThread)
}; Timer::TimerThread* Timer::TimerThread::instance = nullptr;
Timer::TimerThread::LockType Timer::TimerThread::lock; //==============================================================================
Timer::Timer() noexcept
: timerCountdownMs (0),
timerPeriodMs (0),
previousTimer (nullptr),
nextTimer (nullptr)
{
} Timer::Timer (const Timer&) noexcept
: timerCountdownMs (0),
timerPeriodMs (0),
previousTimer (nullptr),
nextTimer (nullptr)
{
} Timer::~Timer()
{
stopTimer();
} void Timer::startTimer (const int interval) noexcept
{
// If you're calling this before (or after) the MessageManager is
// running, then you're not going to get any timer callbacks!
jassert (MessageManager::getInstanceWithoutCreating() != nullptr); const TimerThread::LockType::ScopedLockType sl (TimerThread::lock); if (timerPeriodMs == 0)
{
timerCountdownMs = interval;
timerPeriodMs = jmax (1, interval);
TimerThread::add (this);
}
else
{
TimerThread::resetCounter (this, interval);
}
} void Timer::startTimerHz (int timerFrequencyHz) noexcept
{
if (timerFrequencyHz > 0)
startTimer (1000 / timerFrequencyHz);
else
stopTimer();
} void Timer::stopTimer() noexcept
{
const TimerThread::LockType::ScopedLockType sl (TimerThread::lock); if (timerPeriodMs > 0)
{
TimerThread::remove (this);
timerPeriodMs = 0;
}
} void JUCE_CALLTYPE Timer::callPendingTimersSynchronously()
{
if (TimerThread::instance != nullptr)
TimerThread::instance->callTimersSynchronously();
}

  

juce中的timer的更多相关文章

  1. iOS中的NSTimer 和 Android 中的Timer

    首先看iOS的, Scheduling Timers in Run Loops A timer object can be registered in only one run loop at a t ...

  2. .NET中的Timer类型用法详解

    这篇文章主要介绍了.NET中的Timer类型用法,较为详细的分析了Timer类型在各种环境下的用法,需要的朋友可以参考下   在.NET FrameWork中有多个Timer,那么怎么根据实际情况进行 ...

  3. 【JavaScript】JavaScript中的Timer是怎么工作的( setTimeout,setInterval)

    原文(http://www.yeeyan.org/articles/view/luosheng/24380) 作为入门者来说,了解JavaScript中timer的工作方式是很重要的.通常它们的表现行 ...

  4. juce中的BailOutChecker

    界面库中值得注意的一点就是对象响应事件的时候自身被删除了,那么后续的访问自然就会出问题,所以需要在响应事件之后先添加引用,相关处理之后再查看自身是否已经被删除,如果已经被删除那么就直接退出.juce中 ...

  5. juce 中的WeakReference分析

    juce中的WeakReference设计得比较巧妙,巧妙就是使用delete之后就可以通知道WeakReference,原理其实也很间单,其实就是在对象里添加了一个子对象masterReferenc ...

  6. ASP.NET AJAX入门系列(11):在多个UpdatePanle中使用Timer控件

    本文将使用Timer控件更新两个UpdatePanel控件,Timer控件将放在UpdatePanel控件的外面,并将它配置为UpdatePanel的触发器,翻译自官方文档. 主要内容 在多个Upda ...

  7. C# windows服务:C#windows服务中的Timer控件的使用

    C# windows服务程序中的Timer控件的使用问题是如何解决的呢? 今天和同事一起研究了下C# windows服务程序中的Timer控件的使用的写法. 我们在建立一个C# windows服务程序 ...

  8. Boost中的Timer的使用——计算时间流逝

    使用Boost中的Timer库计算程序的运行时间 程序开发人员都会面临一个共同的问题,即写出高质量的代码完毕特定的功能.评价代码质量的一个重要标准就是算法的运行效率,也就是算法的运行时间.为了可靠的提 ...

  9. Java中定时器Timer致命缺点(附学习方法)

    简介 这篇文章我一直在纠结到底要不要写,不想写一来因为定时器用法比较简单,二来是面试中也不常问.后来还是决定写了主要是想把自己分析问题思路分享给大家,让大家在学习过程中能够参考,学习态度我相信大部分人 ...

随机推荐

  1. Core Bluetooth下实现两个设备进行互联

    一.外设管理者 - 发布广告 如果两部手机在BLE的基础上进行连接,需要让其中一部手机作为外设,外设需要进行广播自己需要发布的数据,以供中心设备的接收和处理. 实现外设广播数据并且处理发送过程当中的流 ...

  2. NodeJS初学者实战之旅(I) —— 介绍、目录

    旅行之初 作为一个工作了两年多后端开发人员,未接触过NodeJS,对它的认知也仅仅停留在“可以使用JavaScript代码编写服务端程序”上.最近空闲时间 较多,便想来啃它一啃.但是没有一个实际的玩意 ...

  3. jQuery.on() 函数详解

    on() 函数用于为指定元素的一个或多个事件绑定事件处理函数. 此外,你还可以额外传递给事件处理函数一些所需的数据. 从jQuery 1.7开始,on()函数提供了绑定事件处理程序所需的所有功能,用于 ...

  4. IE的documentMode属性

    参看下面链接:<IE的documentModeshuxing>

  5. php讲中文json数据编码

    <?php function show_jsonmsg($data){ if(is_array($data)){ $return = $data; }else{ $return = array( ...

  6. Java、Tomcat 及 MySQL 环境配置

    Java开发环境的配置 首先我们要下载JDK. 到Oracle官网上去下载即可,目前最新版是Java SE 8u25. 开始我很混乱,Java SE 和 JDK是什么关系呢?最后查了一下 Java S ...

  7. HTML5的结构学习(1) --- 新增的主体结构元素

      1.article 元素 解释:代表文档.页面和应用程序中独立的.完整的.可以被独自引用的内容. 主要用途:博客中的文章.评论,贴吧中的帖子,或者独立的插件等. article中可以包含多种元素例 ...

  8. 简单C# 验证类

    using System; using System.Text.RegularExpressions; namespace bobomousecom.crm { /// <summary> ...

  9. java性能优化技巧

    在JAVA程序中,性能问题的大部分原因并不在于JAVA语言,而是程序本身.养成良好的编码习惯非常重要,能够显著地提升程序性能. 1. 尽量使用final修饰符. 带有final修饰符的类是不可派生的. ...

  10. 使用Python脚本获取指定格式文件列表的方法

    在Python环境下获取指定后缀文件列表的方式. 来源stackoverflow 这里简单以*.txt的作为例子. 使用glob(推荐) import glob, os os.chdir(" ...