-
Notifications
You must be signed in to change notification settings - Fork 22
CoreModifiable methods
CoreModifiable methods are methods that can be called by their name without knowing the exact type of the called instance.
Fixed prototype is :
bool methodName(CoreModifiable* sender,std::vector<CoreModifiableAttribute*>& params,void* privateParams);
Parameters are :
- CoreModifiable* sender : caller class
- std::vector<CoreModifiableAttribute*>& params : vector of CoreModifiableAttribute* parameters
- void* privateParams : a possible user-defined private param
The return value is a bool value. The meaning of the return value is user-defined.
Helper macros can be used to declare a member method : DECLARE_METHOD, DECLARE_VIRTUAL_METHOD, DECLARE_PURE_VIRTUAL_METHOD, DECLARE_OVERRIDE_METHOD.
// declare member method called "GiveInfos"
DECLARE_METHOD(GiveInfos);
Then COREMODIFIABLE_METHODS must be used to list all the methods declared with one of the previous helper macro ( or directly using the CoreModifiable method prototype ) :
// list all CoreModifiable methods
COREMODIFIABLE_METHODS(GiveInfos);
Helper macro DEFINE_METHOD is then used to 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;
}
Then method can be called with "CallMethod" like this :
// create dynamic attribute on this
AddDynamicAttribute<maFloat, float>("FloatParam", 12.0f);
// create CoreModifiableAttribute without owner
CoreModifiableAttribute* intParam = new maIntOrphan("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;
The SimpleCall template method automatically encode parameters in vector :
// "SimpleCall" on instance2:
result = instance2->SimpleCall("GiveInfos", 32,64,5);
std::cout << "GiveInfos returns " << (result ? "true" : "false") << std::endl << std::endl;
Returned value can be pushed on parameter vector with helper macro PUSH_RETURN_VALUE. When called using CallMethod, the returned value must be delete (or a memory leak will occur).
// 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)
{
// a return was value added
while(paramsCount<params.size())
{
std::string v;
if(params.back()->getValue(v,nullptr))
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;
With SimpleCall, the returned value can be managed automatically with template parameter :
// "SimpleCall" on instance2:
float floatresult = instance2->SimpleCall<float>("GiveInfos", 32,64,5);
std::cout << "GiveInfos returns " << floatresult << std::endl << std::endl;
Any member method can be wrapped as a CoreModifiable method. In class declaration :
float Multiply(float v1, float v2)
{
return v1 * v2;
}
// Multiply method can be called with SimpleCall
WRAP_METHODS(Multiply);
Then Multiply method can be called like this :
float floatresult = instance2->SimpleCall<float>("Multiply", 32, 5);
std::cout << "instance2 Multiply returns " << floatresult << std::endl << std::endl;
CoreModifiable inherited instances can be "enhanced" with dynamic method.
A dynamic method can be define like this :
// 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;
}
Then at run time, add this method to a given instance, and call it with 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;
This mechanism can be used to decorate instances with a specific behaviour.
Find all the sample code from this wiki section in Sample4 project (browse the code)
Kigs framework Wiki - kigs-framework.org
-
3.1. CoreModifiable
3.1.1. Upgrador
3.2. Attributes
3.3. Methods
3.4. CoreItem
3.6. Lua Binding
-
Other Modules
4.1. FileManager
4.2. Timer
4.3. 2DLayers
4.4. Collision
4.5. GUI
4.6. Input
4.7. SceneGraph
4.8. Renderer