Kigs框架介绍 (4/8) - 方法






3.55/5 (7投票s)
一个多用途、跨平台、免费且开源的C++框架。本文将重点介绍CoreModifiable方法。
目录
引言
查看 已在此系列中发布 部分以了解之前的内容。
在本文中,我们将重点介绍CoreModifiable
方法。CoreModifiable
方法是可以按名称调用的方法,无需知道被调用实例的确切类型。
快速访问固定原型方法
固定原型是
bool methodName(CoreModifiable* sender,
std::vector<CoreModifiableAttribute*>& params,void* privateParams);
参数是
CoreModifiable* sender
: 调用者类std::vector<CoreModifiableAttribute*>& params
:CoreModifiableAttribute*
参数的vector
void* privateParams
: 一个可能的用户定义的私有参数
返回值是bool
值。返回值的含义由用户定义。
可以使用帮助宏来声明成员方法:DECLARE_METHOD
、DECLARE_VIRTUAL_METHOD
、DECLARE_PURE_VIRTUAL_METHOD
、DECLARE_OVERRIDE_METHOD
。
// declare member method called "GiveInfos"
DECLARE_METHOD(GiveInfos);
然后必须使用COREMODIFIABLE_METHODS来列出使用前一个辅助宏之一声明的所有方法(或直接使用CoreModifiable方法原型)
// list all CoreModifiable methods
COREMODIFIABLE_METHODS(GiveInfos);
然后使用辅助宏DEFINE_METHOD
来定义方法
// define member method named GiveInfos on SimpleClass
DEFINE_METHOD(SimpleClass, GiveInfos)
{
std::cout << "SimpleClass GiveInfos method called on
" << getName() << " instance" << std::endl;
std::cout << "-- sender : " << sender->getName() << std::endl;
for (auto p : params)
{
std::string v;
if (p->getValue(v,this))
{
std::cout << "-- parameter : " << p->id() <<
" value is : " << v << std::endl;
}
else
{
std::cout << "-- parameter : " << p->id() <<
" value cannot be evaluated as string" << std::endl;
}
}
if(privateParams)
std::cout << "-- private parameter is not null" << std::endl;
else
std::cout << "-- private parameter is null" << std::endl;
return true;
}
快速调用
然后可以使用“CallMethod
”调用方法,如下所示
// create dynamic attribute on this
AddDynamicAttribute<maFloat, float>("FloatParam", 12.0f);
// create CoreModifiableAttribute without owner
CoreModifiableAttribute* intParam = new maInt("IntParam", 15);
// create a parameter vector
std::vector<CoreModifiableAttribute*> params;
// push dynamic attribute "FloatParam" on vector
params.push_back(getAttribute("FloatParam"));
// push intParam
params.push_back(intParam);
// call GiveInfos on instance1 with params vector, private parameter and sender are nullptr
bool result = instance1->CallMethod("GiveInfos", params, nullptr, nullptr);
std::cout << "GiveInfos returns " << (result?"true":"false") << std::endl << std::endl;
较慢的简单调用
SimpleCall
模板方法自动将参数编码到向量中
// "SimpleCall" on instance2:
result = instance2->SimpleCall("GiveInfos", 32,64,5);
std::cout << "GiveInfos returns " << (result ? "true" : "false") << std::endl << std::endl;
返回值
可以使用辅助宏PUSH_RETURN_VALUE
将返回值推入参数向量中。
使用CallMethod
调用时,必须在调用后删除返回值和分配的参数(否则将发生内存泄漏)。
// call GiveInfos on instance2 with params vector, private parameter and sender are nullptr
int paramsCount = params.size();
result = instance2->CallMethod("GiveInfos", params, nullptr, nullptr);
if (params.size() > paramsCount)
{
// return values added
while(paramsCount<params.size())
{
std::string v;
if(params.back()->getValue(v,this))
std::cout << "GiveInfos returned value = " << v << std::endl;
delete params.back();
params.pop_back();
}
}
std::cout << "GiveInfos returns " << (result ? "true" : "false") << std::endl << std::endl;
使用SimpleCall
,可以使用模板参数自动管理返回值
// "SimpleCall" on instance2:
float floatresult = instance2->SimpleCall<float>("GiveInfos", 32,64,5);
std::cout << "GiveInfos returns " << floatresult << std::endl << std::endl;
较慢的访问包装方法
任何成员方法都可以包装为CoreModifiable
方法。在类声明中
float Multiply(float v1, float v2)
{
return v1 * v2;
}
// Multiply method can be called with SimpleCall
WRAP_METHODS(Multiply);
然后可以这样调用Multiply
方法
float floatresult = instance2->SimpleCall<float>("Multiply", 32, 5);
std::cout << "instance2 Multiply returns " << floatresult << std::endl << std::endl;
动态方法
CoreModifiable
继承的实例可以使用动态方法进行增强。
可以这样定义动态方法
// declare a dynamic method named addValues which can be added to any CoreModifiable instance
DEFINE_DYNAMIC_METHOD(CoreModifiable, addValues)
{
float result = 0.0f;
for (auto p : params)
{
float v;
if (p->getValue(v,this))
{
result += v;
}
}
PUSH_RETURN_VALUE(result);
return true;
}
然后在运行时,将此方法添加到给定的实例,并使用SimpleCall
调用它
// now add addValues method on instance2, calling name is also addValues
instance2->INSERT_DYNAMIC_METHOD(addValues, addValues);
floatresult = instance2->SimpleCall<float>("addValues", 32, 5);
std::cout << "instance2 addValues returns " << floatresult << std::endl << std::endl;
此机制可用于使用特定行为来修饰实例。
在Sample4项目(浏览代码)中查找本文中的所有示例代码。
已在此系列中发布
- 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月13日:初始版本
- 2020年2月21日:文章 (5/8) 添加到该系列
- 2020年3月3日:文章 (6/8) 添加到该系列
- 2020年3月19日:文章 (7/8) 添加到该系列
- 2020年6月17日:添加了该系列的最后一篇文章
- 2023年3月1日:框架重构后文章更新