Jump to content

Entity::CallFunction - Specify Parameters?


T0X1N
 Share

Recommended Posts

How do I specify parameters in C++ with Entity::CallFunction?

 

Example, I have a "Hurt" function defined as the following:

 

function Script:Hurt( damage )

 

In my C++ program, I want to call the "Hurt" function and specify the "damage". I found an old forum post (http://www.leadwerks.com/werkspace/topic/10745-passing-parameters-to-lua-via-callfunction/page__hl__entity::callfunction#entry78846), but I still do not understand how to specify parameters.

 

I would like to do the following in my C++ program:

 

entity->CallFunction("Hurt", damage)

Play Our Latest Game: Relic Rogue

Link to comment
Share on other sites

There are a few different declarations of the function with different parameters. The one you describe above is not one.

 

However, if you understand how the Lua stack works you can call any type of Lua functoin from C++. Here is my source code:

    bool Entity::CallFunction(const std::string& name, Object* extra)

{

if (component==NULL) return false;

bool success = false;

 

//Get the stack size to restore

int stacksize = Interpreter::GetStackSize();

 

//Get the global error handler function

int errorfunctionindex = 0;

#ifdef DEBUG

Interpreter::GetGlobal("LuaErrorHandler");

errorfunctionindex = Interpreter::GetStackSize();

#endif

Push();

Interpreter::GetField("script");

if (Interpreter::IsTable())

{

Interpreter::GetField(name);

if (Interpreter::IsFunction())

{

Interpreter::PushValue(-2);//Push script table onto stack

extra->Push();

#ifdef DEBUG

errorfunctionindex = -(Interpreter::GetStackSize()-errorfunctionindex+1);

#endif

success = Interpreter::Invoke(2,0,errorfunctionindex);

}

}

Interpreter::SetStackSize(stacksize);

return success;

}

 

Instead of extra->Push(), which is the same thing as calling Interpreter::PushObject(extra) you would call Interpreter::PushInt(damage). The Invoke function has two arguments, the entity itself and the number you supply.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

I don't think I quite understand this yet.

 

Do I have to write a Entity::CallFunction function in my c++ source code? If I do, how would I go about adding the int "damage" to the code since I cannot create a new declaration to the Entity:: class. Plus, would this function act as a Hook function?

 

What is the "extra" object? Can't I use that to store the data in? If so, how could I go about storing the 'damage' variable into an Object class variable?

 

Also, is it possible to have an example source code snippet that calls a function in LUA from C++ with custom parameters that I can look at to learn off of? That would be extremely helpful as I learn by example mainly.

 

Thanks for the help! smile.png

Play Our Latest Game: Relic Rogue

Link to comment
Share on other sites

That's what I posted above. That is the source code of the CallFunction() function. You can modify this, although you cannot make it a class function, so it would be something more like this:

CallEntityFunction(Entity* entity, const std::string& name, const int i)

 

My function passes an object to the Lua function. You want a function that passes an integer instead.

 

So instead of adding the "extra" object parameter to the stack, add an integer with Interpreter::PushInt().

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Ok, now we are cooking. However, I am facing some issues. Here is my function that I wrote which is basically a duplication of the CallFunction source that you posted with a few edits to just use "Hurt" function.

 

bool FPSplayer::CallHurtFunction(Entity* entity, const int damage){

if (entity->component == NULL){
System::Print("ENTITY COMPONENT IS NULL!");
return false;
}
bool success = false;

//Get the stack size to restore
int stacksize = Interpreter::GetStackSize();

//Get the global error handler function
int errorfunctionindex = 0;
#ifdef DEBUG
Interpreter::GetGlobal("LuaErrorHandler");
errorfunctionindex = Interpreter::GetStackSize();
#endif
entity->Push();
Interpreter::GetField("script");
if (Interpreter::IsTable())
{
Interpreter::GetField("Hurt");
if (Interpreter::IsFunction())
{
System::Print("HURT FUNCTION EXISTS...");
Interpreter::PushValue(-2);//Push script table onto stack
Interpreter::PushInt(damage);

#ifdef DEBUG
errorfunctionindex = -(Interpreter::GetStackSize() - errorfunctionindex + 1);
#endif
success = Interpreter::Invoke(2, 0, errorfunctionindex);
}else{
System::Print("GetField(HURT) is False \n");
}
} else {
System::Print("IsTable() is false \n");
}
Interpreter::SetStackSize(stacksize);
return success;
}

 

 

and I am calling the function using this

 

if( pickInfo.entity->ContainsFunction("Hurt") ){
// CALL HURT FUNCTION
System::Print("HAS HURT FUNCTION... Calling! \n");
CallHurtFunction(pickInfo.entity, damage);
}else if( pickInfo.entity->parent != NULL ){
if (pickInfo.entity->parent->ContainsFunction("Hurt")) {
System::Print("HAS HURT FUNCTION... & Parent... calling! \n");
CallHurtFunction(pickInfo.entity, damage);
}
}

 

However, it comes back that 'component' is NULL. If I take that away, the 'Interpreter::IsTable()' comes back false. I know I am doing something wrong here, obviously, as this is new to me.

 

Again, thanks for the help. I really appreciate this. :)

Play Our Latest Game: Relic Rogue

Link to comment
Share on other sites

Ah, yup! You were right! In my code when I call the function, I forgot to tell it to call the function using the entity's parent script (which is the one that has the script). After fixing that, it works perfectly.

 

Here is the fixed code:

 

if( pickInfo.entity->ContainsFunction("Hurt") ){
// CALL HURT FUNCTION
CallHurtFunction(pickInfo.entity, damage);
}else if( pickInfo.entity->parent != NULL ){
if (pickInfo.entity->parent->ContainsFunction("Hurt")) {
CallHurtFunction(pickInfo.entity->parent, damage);
}
}

 

Thank you for helping me. I can now say I learned something new today with Leadwerks and now a just another step closer to getting our game done! :)

  • Upvote 1

Play Our Latest Game: Relic Rogue

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...