查看venusmmi的代码时,经常会看到以下的代码:
VFX_OBJ_CREATE(m_delayPenDownTimer, VfxTimer, this);
m_delayPenDownTimer->m_signalTick.connect(this, &VappKeyMainmenuPageMenu::onDelayPenDownTimerTick);
代码的意思很明了,就是创建一个定时器,然后超时的时候自动进行相关的操作。发现这个很好用,很方便,决定研究一下是怎么实现的。
以vfxsignal1为例:
/*****************************************************************************
* Class VfxSignal1
*****************************************************************************/
/*
* Signal with one parameter
*/
template <class _arg1_type> //类模板,<span style="font-family: Arial, Helvetica, sans-serif;">_arg1_type为虚拟类型参数</span>
class VfxSignal1 : public VfxBaseSignal
{
VFX_DECLARE_NO_COPY_CLASS(VfxSignal1);
private:
typedef void (VfxObject::*obj_mem_funcptr_type)(_arg1_type arg1);
typedef VfxSignalArg1 <_arg1_type> Argument;
public:
// default constructor
VfxSignal1()
{
}
// Set the default slot
template <class _func_type>
void connectFront(VfxObject *obj, _func_type func)
{
baseConnectFront(obj, (VfxSlotObjMemFuncPtr)VFX_STATIC_CAST(func, obj_mem_funcptr_type));
}
// connect to a member-to-function pointer
template <class _func_type>
void connect(VfxObject *obj, _func_type func)
{
baseConnect(obj, (VfxSlotObjMemFuncPtr)VFX_STATIC_CAST(func, obj_mem_funcptr_type));
}
// disconnect from a member-to-function pointer
template <class _func_type>
void disconnect(VfxObject *obj, _func_type func)
{
baseDisconnect(obj, (VfxSlotObjMemFuncPtr)VFX_STATIC_CAST(func, obj_mem_funcptr_type));
}
// connect to a callback object
void connect(VfxCallback1<_arg1_type> cb)
{
baseConnect(cb.m_objPtr.get(), cb.m_callback);
}
// disconnect from a callback object
void disconnect(VfxCallback1<_arg1_type> cb)
{
baseDisconnect(cb.m_objPtr.get(), cb.m_callback);
}
// invoke a single signal function
static void emitEntry(VfxObject *obj, VfxSlotObjMemFuncPtr callback, VfxSignalArg *arguments)
{
Argument* arg = (Argument*) arguments;
(obj->* obj_mem_funcptr_type(callback))(arg->arg1);
}
// trigger this signal
void emit(_arg1_type arg1) const
{
if (!m_slotList.isEmpty())
{
Argument arg(arg1);
VfxSlotList tmpSlotList(m_slotList);
emitSlots(&tmpSlotList, (VfxEmitEntryFuncPtr)&VfxSignal1::emitEntry, (void*)&arg);
}
}
// post emit a signal
template <class _func_type>
void postEmit(
_arg1_type arg1,
VfxObject *obj, // [IN] after emiting the signal, callback to which object
_func_type func // [IN] after emiting the signal, callback to which member function of this object
) const
{
Argument *arg;
VFX_SYS_NEW_EX(arg, Argument, (arg1));
VFX_REG_POSTEMIT(VfxSignal1, arg, obj, func);
}
// post emit a signal without callback
void postEmit(
_arg1_type arg1
) const
{
if (!m_slotList.isEmpty())
{
Argument *arg;
VFX_SYS_NEW_EX(arg, Argument, (arg1));
VFX_REG_POSTEMIT(VfxSignal1, arg, NULL, NULL);
}
}
}