完成强类型事件委托,测试通过!

支持全局函数、静态成员函数和实例成员函数,作为事件处理函数。
This commit is contained in:
Stone 2016-06-18 09:48:12 +00:00
parent e68d5185e5
commit f5caa8a664
30 changed files with 222 additions and 191 deletions

View File

@ -55,7 +55,7 @@ void Button::OnPress(Pin pin, bool down)
SetValue(!_Value);
//if(_Handler) _Handler(this, _Param);
Press(this);
Press(*this);
}
}

View File

@ -25,7 +25,7 @@ public:
OutputPort Led; // 指示灯
OutputPort Relay; // 继电器
Delegate Press; // 按下事件
Delegate<Button&> Press; // 按下事件
public:
// 构造函数。指示灯和继电器一般开漏输出,需要倒置

View File

@ -120,14 +120,14 @@ void Button_GrayLevel::OnKeyPress(InputPort* port, bool down)
}
SetValue(!_Value);
//if (_Handler) _Handler(this, _Param);
Press(this);
Press(*this);
break;
case set:
Stat = normal;
Next = 0xff;
SetValue(!_Value);
//if (_Handler) _Handler(this, _Param);
Press(this);
Press(*this);
break;
}
}
@ -231,8 +231,7 @@ bool Button_GrayLevel::SetACZeroPin(Pin aczero)
return false;
}
void Button_GrayLevel::Init(TIMER tim, byte count, Button_GrayLevel* btns, Action onpress
, const ButtonPin* pins, byte* level, const byte* state)
void Button_GrayLevel::Init(TIMER tim, byte count, Button_GrayLevel* btns, TAction onpress, const ButtonPin* pins, byte* level, const byte* state)
{
debug_printf("\r\n初始化开关按钮 \r\n");

View File

@ -23,6 +23,9 @@ enum ButtonStat :byte
execution = 3, // 执行设置
};
class Button_GrayLevel;
using TAction = Delegate<Button_GrayLevel&>::Action;
// 面板按钮
// 这里必须使用_packed关键字生成对齐的代码否则_Value只占一个字节导致后面的成员进行内存操作时错乱
//__packed class Button
@ -45,7 +48,7 @@ public:
void * ExterSetParam = nullptr;
public:
Delegate Press;
Delegate<Button_GrayLevel&> Press;
// 构造函数。指示灯和继电器一般开漏输出,需要倒置
Button_GrayLevel();
@ -82,7 +85,7 @@ public:
static byte OnGrayLevel; // 开灯时 led 灰度
static byte OffGrayLevel; // 关灯时 led 灰度
static void Init(TIMER tim, byte count, Button_GrayLevel* btns, Action onpress, const ButtonPin* pins, byte* level, const byte* state);
static void Init(TIMER tim, byte count, Button_GrayLevel* btns, TAction onpress, const ButtonPin* pins, byte* level, const byte* state);
static void InitZero(Pin zero, int us = 2300);
static bool UpdateLevel(byte* level, Button_GrayLevel* btns, byte count);

View File

@ -73,7 +73,7 @@ void Button_magnetic::OnPress(Pin pin, bool down)
SetValue(!_Value);
//if(_Handler) _Handler(this, _Param);
Press();
Press(*this);
}
}

View File

@ -25,7 +25,7 @@ private:
public:
cstring Name;
Delegate Press;
Delegate<Button_magnetic&> Press;
InputPort* Key; // 输入按键
OutputPort* Led; // 指示灯

View File

@ -65,7 +65,7 @@ void Sensor::OnPress(Pin pin, bool down)
SetValue(!_Value);
//if(_Handler) _Handler(this, _Param);
Press();
Press(*this);
}
}

View File

@ -21,7 +21,7 @@ public:
//I2C* Ifrared //红外转发
Delegate Press;
Delegate<Sensor&> Press;
// 构造函数。指示灯和继电器一般开漏输出,需要倒置
Sensor() { Init(); }

View File

@ -49,7 +49,7 @@ void Music::Sound()
{
_timer->SetFrequency(100000);
//_timer->Register(TimerHander, this);
_timer->Register(Delegate(&Music::TimerHander, this));
_timer->Register(Delegate<Timer&>(&Music::TimerHander, this));
_timer->Open();
Sounding = true;
}
@ -83,7 +83,7 @@ bool Music::getStat()
return Sounding;
}
void Music::TimerHander(Timer* timer)
void Music::TimerHander(Timer& timer)
{
/*if(param == nullptr)return;
Music * music = (Music * )param;

View File

@ -37,7 +37,7 @@ private:
volatile int sound_cnt;
volatile int music_freq;
volatile int music_beat;
void TimerHander(Timer* timer);
void TimerHander(Timer& timer);
void phonate();
};

View File

@ -147,10 +147,8 @@ static void On_DHCP_Ready(void* param)
if (_DHCP_Ready) _DHCP_Ready(param);
}
static void OnDhcpStop(void* sender, void* param)
static void OnDhcpStop(Dhcp& dhcp)
{
auto& dhcp = *(Dhcp*)sender;
// DHCP成功或者失败且超过最大错误次数都要启动网关让它以上一次配置工作
if (dhcp.Result || dhcp.Times >= dhcp.MaxTimes)
{

View File

@ -150,10 +150,8 @@ static void On_DHCP_Ready(void* param)
if(_DHCP_Ready) _DHCP_Ready(param);
}
static void OnDhcpStop(void* sender, void* param)
static void OnDhcpStop(Dhcp& dhcp)
{
auto& dhcp = *(Dhcp*)sender;
// DHCP成功或者失败且超过最大错误次数都要启动网关让它以上一次配置工作
if(dhcp.Result || dhcp.Times >= dhcp.MaxTimes)
{

View File

@ -76,10 +76,8 @@ static void On_DHCP_Ready(void* param)
if(_DHCP_Ready) _DHCP_Ready(param);
}
static void OnDhcpStop(void* sender, void* param)
static void OnDhcpStop(Dhcp& dhcp)
{
auto& dhcp = *(Dhcp*)sender;
// DHCP成功或者失败且超过最大错误次数都要启动网关让它以上一次配置工作
if(dhcp.Result || dhcp.Times >= dhcp.MaxTimes)
{

View File

@ -107,10 +107,8 @@ static void On_DHCP_Ready(void* param)
if(_DHCP_Ready) _DHCP_Ready(param);
}
static void OnDhcpStop(void* sender, void* param)
static void OnDhcpStop(Dhcp& dhcp)
{
auto& dhcp = *(Dhcp*)sender;
// DHCP成功或者失败且超过最大错误次数都要启动网关让它以上一次配置工作
if(dhcp.Result || dhcp.Times >= dhcp.MaxTimes)
{

View File

@ -5,51 +5,13 @@
#include "Delegate.h"
/************************************************ Delegate ************************************************/
Delegate::Delegate()
/*Delegate::Delegate()
{
Method = nullptr;
Target = nullptr;
}
Delegate::Delegate(void* func) { Method = (void*)func; Target = nullptr; }
Delegate::Delegate(void* func, void* target){ Method = (void*)func; Target = target; }
Delegate::Delegate(Func func) { Method = (void*)func; Target = nullptr; }
Delegate::Delegate(Action func) { Method = (void*)func; Target = nullptr; }
Delegate::Delegate(Action2 func){ Method = (void*)func; Target = nullptr; }
Delegate::Delegate(Action3 func){ Method = (void*)func; Target = nullptr; }
Delegate& Delegate::operator=(void* func) { Method = (void*)func; return *this; }
Delegate& Delegate::operator=(Func func) { Method = (void*)func; return *this; }
Delegate& Delegate::operator=(Action func) { Method = (void*)func; return *this; }
Delegate& Delegate::operator=(Action2 func) { Method = (void*)func; return *this; }
Delegate& Delegate::operator=(Action3 func) { Method = (void*)func; return *this; }
void Delegate::operator()()
{
if(!Method) return;
if(Target)
((Action)Method)(Target);
else
((Func)Method)();
}
void Delegate::operator()(void* arg)
{
if(!Method) return;
if(Target)
((Action2)Method)(Target, arg);
else
((Action)Method)(arg);
}
void Delegate::operator()(void* arg, void* arg2)
{
if(!Method) return;
if(Target)
((Action3)Method)(Target, arg, arg2);
else
((Action2)Method)(arg, arg2);
}
*/

View File

@ -12,74 +12,171 @@ typedef void (*EventHandler)(void* sender, void* param);
// 传入数据缓冲区地址和长度,如有反馈,仍使用该缓冲区,返回数据长度
typedef uint (*DataHandler)(void* sender, byte* buf, uint size, void* param);
// 事件处理器
// 委托。第一参数目标对象指针,第二泛型参数
template <typename TArg>
class Delegate
{
public:
typedef void(*Action)(TArg);
void* Method; // 函数指针
void* Target; // 参数
Delegate();
Delegate(const Delegate& dlg) = delete;
Delegate(void* func);
Delegate(void* func, void* target);
Delegate(Func func);
Delegate(Action func);
Delegate(Action2 func);
Delegate(Action3 func);
template<typename T>
Delegate(void(T::*func)(), T* target) { Method = (void*)&func; Target = target; }
template<typename T, typename TArg>
Delegate(void(T::*func)(TArg), T* target) { Method = (void*)&func; Target = target; }
template<typename T, typename TArg, typename TArg2>
Delegate(void(T::*func)(TArg, TArg2), T* target) { Method = (void*)&func; Target = target; }
Delegate& operator=(void* func);
Delegate& operator=(Func func);
Delegate& operator=(Action func);
Delegate& operator=(Action2 func);
Delegate& operator=(Action3 func);
void operator()();
void operator()(void* arg);
void operator()(void* arg, void* arg2);
template<typename T>
void operator()()
Delegate()
{
if(Method)
{
auto obj = (T*)Target;
typedef void(T::*TAction)();
auto act = *(TAction*)Method;
(obj->*act)();
}
Method = nullptr;
Target = nullptr;
}
template<typename T, typename TArg>
Delegate(const Delegate& dlg) = delete;
Delegate(Action func) // 全局函数或类静态函数
{
Method = (void*)func;
Target = nullptr;
}
template<typename T>
Delegate(void(*func)(T&, TArg), T* target)
{
Method = (void*)func;
Target = target;
}
template<typename T>
Delegate(void(T::*func)(TArg), T* target) { Method = (void*)&func; Target = target; }
Delegate& operator=(Action func) // 全局函数或类静态函数
{
Method = (void*)func;
Target = nullptr;
return *this;
}
void operator()(TArg arg)
{
if(Method)
{
auto obj = (T*)Target;
typedef void(T::*TAction)(TArg);
auto act = *(TAction*)Method;
if(Target)
{
typedef void(*TAction)(void*, TArg);
auto act = *(TAction*)Method;
(obj->*act)(arg);
(*act)(Target, arg);
}
else
{
//typedef void(*TAction)(TArg);
auto act = *(Action*)Method;
(*act)(arg);
}
}
}
template<typename T, typename TArg, typename TArg2>
void operator()(TArg arg, TArg arg2)
};
//***************************************************************************
// 函数模版接口
template <typename TParameter>
class ifunction
{
public:
// 函数参数的类型
typedef TParameter parameter_type;
// 将被重载的函数操作
virtual void operator ()(TParameter) const = 0;
};
// 无参函数模版接口
template <>
class ifunction<void>
{
public:
typedef void parameter_type;
virtual void operator ()() const = 0;
};
// 对象函数模版
template <typename TObject, typename TParameter>
class function : public ifunction<TParameter>
{
public:
typedef TObject object_type; // 对象类型
typedef TParameter parameter_type; // 函数参数的类型
function(TObject& object, void(TObject::* p_function)(TParameter))
: p_object(&object),
p_function(p_function)
{
if(Method)
{
auto obj = (T*)Target;
typedef void(T::*TAction)(TArg, TArg2);
auto act = *(TAction*)Method;
(obj->*act)(arg, arg2);
}
}
virtual void operator ()(TParameter data) const
{
// 调用对象的成员函数
(p_object->*p_function)(data);
}
private:
TObject* p_object; // 对象指针
void (TObject::* p_function)(TParameter); // 成员函数指针
};
// 对象无参函数模版
template <typename TObject>
class function<TObject, void> : public ifunction<void>
{
public:
function(TObject& object, void(TObject::* p_function)(void))
: p_object(&object),
p_function(p_function)
{
}
virtual void operator ()() const
{
(p_object->*p_function)();
}
private:
TObject* p_object;
void (TObject::* p_function)();
};
// 全局函数模版
template <typename TParameter>
class function<void, TParameter> : public ifunction<TParameter>
{
public:
function(void(*p_function)(TParameter))
: p_function(p_function)
{
}
virtual void operator ()(TParameter data) const
{
(*p_function)(data);
}
private:
void (*p_function)(TParameter);
};
template <>
class function<void, void> : public ifunction<void>
{
public:
function(void(*p_function)(void))
: p_function(p_function)
{
}
virtual void operator ()() const
{
(*p_function)();
}
private:
void (*p_function)();
};
/*
@ -102,29 +199,4 @@ A* pa=&a;
*/
//***************************************************************************
// 对象函数模版
template <typename TArg, typename TArg2>
class function
{
public:
void* Method; // 函数指针
void* Target; // 参数
template <typename TObject>
void bind(TObject& object, void(TObject::* func)(TArg, TArg2))
{
Target = &object;
Method = (void*)&func;
}
virtual void operator ()(TArg arg, TArg2 arg2) const
{
// 调用对象的成员函数
typedef void(*TFunc)(void*, TArg, TArg2);
((TFunc)Method)(Target, arg, arg2);
}
};
#endif //_Delegate_H_

View File

@ -100,7 +100,7 @@ void Timer::Close()
SetHandler(handler != nullptr);
}*/
void Timer::Register(const Delegate& dlg)
void Timer::Register(const Delegate<Timer&>& dlg)
{
OnTick = dlg;
@ -110,7 +110,7 @@ void Timer::Register(const Delegate& dlg)
void Timer::OnInterrupt()
{
//if(_Handler) _Handler(this, _Param);
OnTick(this);
OnTick(*this);
}
/*================ PWM ================*/

View File

@ -10,7 +10,7 @@ class Timer
{
protected:
byte _index; // 第几个定时器从0开始
Delegate OnTick; // 带this参数
Delegate<Timer&> OnTick; // 带this参数
void SetHandler(bool set);
public:
@ -33,7 +33,7 @@ public:
void SetCounter(uint cnt); // 设置计数器值
//void Register(EventHandler handler, void* param = nullptr);
void Register(const Delegate& dlg);
void Register(const Delegate<Timer&>& dlg);
static void ClockCmd(int idx, bool state);

View File

@ -159,7 +159,7 @@ bool Esp8266::OnOpen()
ShowConfig();
}
if(NetReady) NetReady(this);
if(NetReady) NetReady(*this);
return true;
}

View File

@ -745,9 +745,9 @@ IPAddress W5500::QueryDNS(const String& domain)
{
auto ip = IPAddress::Parse(domain);
if(ip != IPAddress::Any()) return ip;
if(_Dns) return _Dns(this, domain);
return ip;
}
@ -760,20 +760,24 @@ static IPAddress FullQueryDNS(ISocketHost* host, const String& domain)
bool W5500::EnableDNS()
{
_Dns = FullQueryDNS;
return true;
}
static void OnDhcpStop(void* sender, void* param)
static void OnDhcpStopTask(void* param)
{
auto& dhcp = *(Dhcp*)sender;
auto& net = *(W5500*)param;
if(net.NetReady) net.NetReady(net);
}
static void OnDhcpStop(W5500& net, Dhcp& dhcp)
{
// DHCP成功或者失败且超过最大错误次数都要启动网关让它以上一次配置工作
if(dhcp.Result || dhcp.Times >= dhcp.MaxTimes)
{
auto callback = (Action)param;
//auto callback = (Action)param;
// 防止调用栈太深,另外开任务
if(callback) Sys.AddTask(callback, &dhcp.Host, 0, -1, "网络就绪");
if(net.NetReady) Sys.AddTask(OnDhcpStopTask, &net, 0, -1, "网络就绪");
}
}
@ -781,14 +785,14 @@ static void OnDhcpStop(void* sender, void* param)
bool W5500::EnableDHCP()
{
if(_Dhcp) return true;
// 打开DHCP
auto dhcp = new Dhcp(*this);
dhcp->OnStop = OnDhcpStop;
dhcp->OnStop = Delegate<Dhcp&>(OnDhcpStop, this);
dhcp->Start();
_Dhcp = dhcp;
return true;
}

View File

@ -15,8 +15,8 @@ Controller::Controller()
MinSize = 0;
Opened = false;
//Received = nullptr;
//Param = nullptr;
Received = nullptr;
Param = nullptr;
}
Controller::~Controller()
@ -134,7 +134,10 @@ bool Controller::OnReceive(Message& msg)
TS("Controller::OnReceive");
// 外部公共消息事件
Received(msg, *this);
if(Received)
{
if(!Received(this, msg, Param)) return true;
}
return true;
}

View File

@ -40,7 +40,7 @@ public:
virtual bool Reply(Message& msg);
// 收到消息时触发
function<Message&, Controller&> Received;
MessageHandler Received;
void* Param;
protected:

View File

@ -201,7 +201,7 @@ void Dhcp::Stop()
}
//if(OnStop) OnStop(this, nullptr);
OnStop(this);
OnStop(*this);
}
void Dhcp::Loop(void* param)

View File

@ -33,7 +33,7 @@ public:
void Start(); // 开始
void Stop(); // 停止
Delegate OnStop; // 带this参数
Delegate<Dhcp&> OnStop; // 带this参数
private:
static uint OnReceive(ITransport* port, Buffer& bs, void* param, void* param2);

View File

@ -32,7 +32,7 @@ public:
String* SSID; // 无线SSID
String* Pass; // 无线密码
typedef void (*NetReadyHandler)(ISocketHost* host);
typedef void (*NetReadyHandler)(ISocketHost& host);
NetReadyHandler NetReady; // 网络准备就绪
ISocketHost();

View File

@ -4,15 +4,15 @@
//Timer* timer;
void TimerTask(OutputPort* leds, Timer* timer)
void TimerTask(OutputPort& led, Timer& timer)
{
*leds = !*leds;
led = !led;
}
uint frequency = 0;
int step = 1;
void TimerTask2(Timer* timer)
void TimerTask2(Timer& timer)
{
frequency += step;
@ -27,24 +27,24 @@ void TimerTask2(Timer* timer)
step = -1;
}
timer->SetFrequency(frequency);
timer.SetFrequency(frequency);
}
void TestTimer(OutputPort& leds)
void TestTimer(OutputPort& led)
{
debug_printf("\r\n");
debug_printf("TestTimer Start......\r\n");
auto timer = new Timer(Timer2);
timer->SetFrequency(50);
//timer->Register(TimerTask, &leds);
timer->Register(Delegate((void*)&TimerTask, &leds));
//timer->Register(TimerTask, &led);
timer->Register(Delegate<Timer&>(TimerTask, &led));
timer->Open();
auto timer2 = Timer::Create();
timer2->SetFrequency(10);
//timer2->Register(TimerTask2, nullptr);
timer2->Register(Delegate((void*)&TimerTask2));
timer2->Register(TimerTask2);
timer2->Open();
debug_printf("\r\n TestTimer Finish!\r\n");

View File

@ -234,10 +234,9 @@ bool CheckUserPress(InputPort* port, bool down, void* param)
return false;
}
void CheckUserPress3(void* sender)
void CheckUserPress3(Button_GrayLevel& btn)
{
auto but = (Button_GrayLevel *)sender;
CheckUserPress(&but->Key, but->Key.Read(), nullptr);
CheckUserPress(&btn.Key, btn.Key.Read(), nullptr);
}
void InitButtonPress(Button_GrayLevel* btns, byte count)

View File

@ -32,10 +32,8 @@
static void StartGateway(void* param);
static void OnDhcpStop(void* sender, void* param)
static void OnDhcpStop(Dhcp& dhcp)
{
auto& dhcp = *(Dhcp*)sender;
// DHCP成功或者失败且超过最大错误次数都要启动网关让它以上一次配置工作
if(dhcp.Result || dhcp.Times >= dhcp.MaxTimes)
{

View File

@ -15,7 +15,7 @@
#include "Security\RC4.h"
//static bool OnTokenClientReceived(void* sender, Message& msg, void* param);
static bool OnTokenClientReceived(void* sender, Message& msg, void* param);
static void LoopTask(void* param);
static void BroadcastHelloTask(void* param);
@ -44,7 +44,7 @@ void TokenClient::Open()
TS("TokenClient::Open");
assert(Control, "令牌客户端还没设置控制器呢");
Control->Received.bind(*this, &TokenClient::OnReceive);
Control->Received = OnTokenClientReceived;
Control->Param = this;
Control->Open();
@ -54,7 +54,7 @@ void TokenClient::Open()
// 向服务端握手时,汇报内网本地端口,用户端将会通过该端口连接
//ctrl = Local;
Local->Received = Control->Received;
Local->Received = OnTokenClientReceived;
Local->Param = this;
Local->Open();
}
@ -111,13 +111,10 @@ bool TokenClient::Reply(TokenMessage& msg, TokenController* ctrl)
return ctrl->Reply(msg);
}
void TokenClient::OnReceive(Message& msg_, Controller& ctrl_)
bool TokenClient::OnReceive(TokenMessage& msg, TokenController* ctrl)
{
TS("TokenClient::OnReceive");
auto& msg = (TokenMessage&)msg_;
auto ctrl = (TokenController*)&ctrl_;
LastActive = Sys.Ms();
switch(msg.Code)
@ -145,7 +142,7 @@ void TokenClient::OnReceive(Message& msg_, Controller& ctrl_)
break;
}
// todo 握手登录心跳消息不需要转发
if(msg.Code < 0x03) return;
if(msg.Code < 0x03) return true;
// 消息转发
if (Received)
@ -162,9 +159,11 @@ void TokenClient::OnReceive(Message& msg_, Controller& ctrl_)
break;
}
}
return true;
}
/*bool OnTokenClientReceived(void* sender, Message& msg, void* param)
bool OnTokenClientReceived(void* sender, Message& msg, void* param)
{
auto ctrl = (TokenController*)sender;
assert_ptr(ctrl);
@ -172,7 +171,7 @@ void TokenClient::OnReceive(Message& msg_, Controller& ctrl_)
assert_ptr(client);
return client->OnReceive((TokenMessage&)msg, ctrl);
}*/
}
// 常用系统级消息

View File

@ -38,7 +38,7 @@ public:
// 发送消息
bool Send(TokenMessage& msg, TokenController* ctrl = nullptr);
bool Reply(TokenMessage& msg, TokenController* ctrl = nullptr);
void OnReceive(Message& msg, Controller& ctrl);
bool OnReceive(TokenMessage& msg, TokenController* ctrl);
// 收到功能消息时触发
MessageHandler Received;