Kigs框架介绍 (6/8) - 信号,槽,通知






2.09/5 (3投票s)
一个多用途、跨平台、免费且开源的 C++ 框架。本文将重点介绍信号/槽和通知机制。
目录
引言
现在我们已经了解了 CoreModifiable
方法的工作方式(Kigs 框架介绍 (4/8) - 方法),我们将在这篇短文中介绍如何利用这种机制轻松地将实例连接在一起。
信号和槽
信号
可以使用辅助宏 SIGNALS
在编译时为给定类声明信号列表
// CoreModifiable signals
SIGNALS(PreInit,
PostInit,
Uninit,
Destroy,
Update, // Called before the actual update
NotifyUpdate,
AddItem,
RemoveItem,
PrepareExport,
EndExport);
然后可以使用方法 "GetSignalList
" 检索该类已声明的信号列表
// get the list of SimpleClass signals
std::cout << "simpleclass instance has following signals available" << std::endl;
auto signallist=simpleclass->GetSignalList();
for (const auto& s : signallist)
{
std::cout << s.toString() << std::endl;
}
槽和连接
可以使用 EmitSignal
方法发出声明的信号
// emit signal with two parameters
EmitSignal(Signals::SendSignal1,32,64);
也可以使用相同的机制发送未声明的信号
// emit a "runtime" signal (not declared with the SIGNALS macro)
EmitSignal("doSomething");
信号可以带或不带参数发出。
要使实例接收来自另一个实例的信号,必须建立连接
// connect this "MethodWithParams" to simpleclass instance "SendSignal1" signal
KigsCore::Connect(simpleclass.get(),"SendSignal1",this, "MethodWithParams");
// connect app undeclared doSomething signal to doSomething method
KigsCore::Connect(app, "doSomething", this, "doSomething");
"MethodWithParams
" 是使用 WRAP_METHODS
宏或 DECLARE_METHOD/COREMODIFIABLE_METHODS
声明的 CoreModifiable
方法。有关详细信息,请参阅本系列中的 CoreModifiable
方法文章。
// Wrapped MethodWithParams
void MethodWithParams(float p1, float p2);
WRAP_METHODS(MethodWithParams);
// fixed prototype CoreModifiable method
DECLARE_METHOD(doSomething);
// list methods
COREMODIFIABLE_METHODS(doSomething);
要断开两个实例的连接,还可以使用 KigsCore::Disconnect
方法
// disconnect this so SendSignal1 will not be catched anymore
CMSP simplecass=GetInstanceByPath("simpleclass");
KigsCore::Disconnect(simplecass.get(), "SendSignal1", this, "MethodWithParams");
Lambda 槽
也可以将信号直接连接到 lambda 函数
// connect to lambda function
KigsCore::Connect(simpleclass.get(), "SendSignal2", this, "lambda", [this](int p1)
{
std::cout << "lambda received parameter " << p1 << std::endl;
});
实例工厂连接
可以要求实例工厂为特定类的每个创建的实例创建连接
// ask instance factory to add a connection on each created SimpleClass
// for the PreInit signal to call this OnSimpleClassPreInit
KigsCore::Instance()->GetInstanceFactory()->addModifiableCallback
("PreInit", this, "OnSimpleClassPreInit", "SimpleClass");
如果未设置最后一个参数,则为所有类型的创建实例添加连接。
要删除自动连接
// remove instance factory auto connection previously set
KigsCore::Instance()->GetInstanceFactory()->removeModifiableCallback
("PreInit", this, "OnSimpleClassPreInit");
Notifications
创建连接的另一种方法是使用 NotificationCenter
类。NotificationCenter
可以像信号/槽机制一样连接两个实例,还可以通知实例侦听任何发送者实例发布的通知。
观察者
NotificationCenter
可以注册观察者实例
// register this as an observer on notification "doSomethingElseNotif"
// call method CatchNotifMethod when doSomethingElseNotif is received
KigsCore::GetNotificationCenter()->addObserver(this,"CatchNotifMethod","doSomethingElseNotif");
第四个 CoreModifiable*
参数可以用于仅侦听来自给定发送者实例的通知。
要删除观察者
// remove this as "doSomethingElseNotif" notification observer.
// a third parameter is needed if observer was set on a specific instance.
KigsCore::GetNotificationCenter()->removeObserver(this, "doSomethingElseNotif");
发布通知
然后可以使用 NotificationCenter
的 "postNotificationName
" 方法发送通知
// post a notification "doSomethingElseNotif"
// a vector of CoreModifiable attributes can be set as second parameter :
// std::vector<CoreModifiableAttribute*>& params
// the sender can also be passed (as second or third parameter)
KigsCore::GetNotificationCenter()->postNotificationName("doSomethingElseNotif", this);
序列化
可以通过将此类项目添加到实例,在 XML 中设置信号/槽连接
<Connect Si="SignalName" E="EmitterPath" SL="SlotName" R="ReceiverPath"/>
Emitter 路径和接收器路径是经典的 CoreModifiable
搜索路径。"this
" 或 "self
" 也可以用于指示拥有实例。
也可以通过添加此项目在实例上设置观察者
<OnE N="NotificationName" A="CalledMethod"/>
在 Sample6 项目中查找此 wiki 部分中的所有示例代码(浏览代码)。
已在此系列中发布
- Kigs框架介绍 (1/8) - 概述
- Kigs框架介绍 (2/8) - CoreModifiable
- Kigs框架介绍 (3/8) - 属性
- Kigs框架介绍 (4/8) - 方法
- Kigs框架介绍 (5/8) - CoreItem
- Kigs框架介绍 (6/8) - 信号,槽,通知
- Kigs框架介绍 (7/8) - Lua绑定
- Kigs框架介绍 (8/8) - 数据驱动应用程序
历史
- 2020年2月26日:初始版本
- 2020年3月19日:文章 (7/8) 已添加到该系列中,并对示例代码进行了一些小修复
- 2020年6月17日:添加了该系列的最后一篇文章
- 2023年3月1日:框架重构后更新文章