C++ call console functions?
by Jacob Wagner · in Torque Game Builder · 02/09/2008 (4:11 am) · 22 replies
Hello, I have a simple question:
How can I call a console function from within the c++ code?
I have already got compiling working, integrating a foreign library, and can call my own hand-crafted console
functions that I made in c++ and have them return values. While this is enough to work with, I'd like the c++ functions to be able to call console functions as well.
I remember reading about this kind of topic before, but I searched pretty extensively and couldn't find the threads.
How can I call a console function from within the c++ code?
I have already got compiling working, integrating a foreign library, and can call my own hand-crafted console
functions that I made in c++ and have them return values. While this is enough to work with, I'd like the c++ functions to be able to call console functions as well.
I remember reading about this kind of topic before, but I searched pretty extensively and couldn't find the threads.
#2
I'm using rakNet as mentioned in the networking thread. I pasted the code I'm using in the thread there. Right now I'm calling a 'receive messages' console function which receives a struct of data from raknet and stores it in a global variable. Then I call individual 'receivex' 'receivey' functions to retrieve the data.
The reason I am doing this is because of 2 reasons: I don't know how to pass all that data as one return value as a console function, and/or I don't know how to call script functions from within a console function :)
Ideally I'd like to do something like this:
Where scriptFunctionConnected is a function I created in torquescript. At that point the c++ code could pass values as arguments to the script function.
The reason I want to do this is so that I can work mostly in torquescript.
You'll see what I mean if you look at my c++ code in the networking thread, although I'd imagine that someone with a better knowledge of c++ would know some mistake I'm making. Alternatively if I just knew how to return several values as one value from a console function, like an array, I'd be set.
02/11/2008 (9:30 am)
I'm not sure I understand this so here is a scenario:I'm using rakNet as mentioned in the networking thread. I pasted the code I'm using in the thread there. Right now I'm calling a 'receive messages' console function which receives a struct of data from raknet and stores it in a global variable. Then I call individual 'receivex' 'receivey' functions to retrieve the data.
The reason I am doing this is because of 2 reasons: I don't know how to pass all that data as one return value as a console function, and/or I don't know how to call script functions from within a console function :)
Ideally I'd like to do something like this:
[raknet code ]
if (connect == true) {
scriptFunctionConnected;
}Where scriptFunctionConnected is a function I created in torquescript. At that point the c++ code could pass values as arguments to the script function.
The reason I want to do this is so that I can work mostly in torquescript.
You'll see what I mean if you look at my c++ code in the networking thread, although I'd imagine that someone with a better knowledge of c++ would know some mistake I'm making. Alternatively if I just knew how to return several values as one value from a console function, like an array, I'd be set.
#4
ScriptMethod(function) -- TorqueScript code that is executed from either other TorqueScript (normal method calling techniques), or from c++ code via a callback.
ConsoleMethod(function) -- a specific type of c++ code (different from "normal" c++ code in some ways) that is intended only to be executed by a call from TorqueScript. It cannot in fact be called directly from another c++ section of code without some very strict understanding of how the engine works, and is not a recommended practice.
Class Method(function) -- c++ code that can be called from other c++ code, but not (directly) from TorqueScript.
Callback -- a technique used to allow c++ code to call a ScriptMethod(function).
Finally, I used the syntax XXMethod(function) above, because the key difference between methods and functions is that methods have namespaces, where functions do not, i.e.
is a TorqueScript Method since it has a namespace, while
is a TorqueScript function, since there is no associated namespace.
Now, in the specific use case you have, where you have code that is written in c++, but you want the flexibility to be able to call it from either other c++, or TorqueScript, the standard technique is two steps:
--create a c++ Class Method that executes your code logic.
--create a ConsoleMethod that simply acts as a "transfer" between TorqueScript and your class method--all it does is turn around and execute your c++ class method.
Finally, the last style is when you have c++ code that needs to call a TorqueScript method/function. This is called a callback, and while there are some details you'll have to look for, the syntax is:
That specific example is right from the source code of TGB 1.7.2 (although it hasn't changed across many versions), which lets the TorqueScript developer know that a specific object ("this') has reached it's world limit, and it's time for TorqueScript to handle that situation if it wants to.
It's sending a total of 3 arguments that will be used by the TorqueScript Method--the objectID of the object in question (this), the action that is going to be taken (the getWorldLimitDescription), and which limit was hit (the limitDescription) section.
I realize this doesn't give you exact specifics about how to re-organize your code, but hopefully it clears things up some theory wise!
02/11/2008 (9:52 am)
This might help to clear things up, so bear with me while I set up some terms and use cases:ScriptMethod(function) -- TorqueScript code that is executed from either other TorqueScript (normal method calling techniques), or from c++ code via a callback.
ConsoleMethod(function) -- a specific type of c++ code (different from "normal" c++ code in some ways) that is intended only to be executed by a call from TorqueScript. It cannot in fact be called directly from another c++ section of code without some very strict understanding of how the engine works, and is not a recommended practice.
Class Method(function) -- c++ code that can be called from other c++ code, but not (directly) from TorqueScript.
Callback -- a technique used to allow c++ code to call a ScriptMethod(function).
Finally, I used the syntax XXMethod(function) above, because the key difference between methods and functions is that methods have namespaces, where functions do not, i.e.
function MyNameSpace::codeToExecute(..)
{
}is a TorqueScript Method since it has a namespace, while
function globalCodeToExecute(..)
{
}is a TorqueScript function, since there is no associated namespace.
Now, in the specific use case you have, where you have code that is written in c++, but you want the flexibility to be able to call it from either other c++, or TorqueScript, the standard technique is two steps:
--create a c++ Class Method that executes your code logic.
--create a ConsoleMethod that simply acts as a "transfer" between TorqueScript and your class method--all it does is turn around and execute your c++ class method.
Finally, the last style is when you have c++ code that needs to call a TorqueScript method/function. This is called a callback, and while there are some details you'll have to look for, the syntax is:
// this is c++ code
Con::executef( this, 3, "onWorldLimit",
getWorldLimitDescription(mWorldLimitMode),
limitDescription );That specific example is right from the source code of TGB 1.7.2 (although it hasn't changed across many versions), which lets the TorqueScript developer know that a specific object ("this') has reached it's world limit, and it's time for TorqueScript to handle that situation if it wants to.
It's sending a total of 3 arguments that will be used by the TorqueScript Method--the objectID of the object in question (this), the action that is going to be taken (the getWorldLimitDescription), and which limit was hit (the limitDescription) section.
I realize this doesn't give you exact specifics about how to re-organize your code, but hopefully it clears things up some theory wise!
#5
02/11/2008 (9:58 am)
I often wish GG had an amanuensis who's sole job was to transcribe Stephen's forum posts over to TDN.
#6
02/11/2008 (10:41 am)
This info is exactly what I needed. Thanks!
#7
02/11/2008 (10:50 am)
@Orion: funny--I often wish we had someone assigned to collect and maintain your utility functions back into the code base! You always come up with great stuff with focused utility, and I've been meaning to do a survey and get them factored in some release cycle, but never have had the time to do it right :(
#8
I think I'm asking the reverse question here. I'm planning on adding on to the engine some specific feature unique to the game. From within torquescript, would I follow the same information to evoke a function that would be part of the engine?
C++
namespace PlayerGroup
int active_player(int ObjectID, *PlayerNode)
{
blah cold
}
within torquescript, is it possible to do
function PlayerGroup::active_player(this, this)
{
// blah code
return 0; after excute
}
03/31/2008 (5:17 pm)
Hmm.I think I'm asking the reverse question here. I'm planning on adding on to the engine some specific feature unique to the game. From within torquescript, would I follow the same information to evoke a function that would be part of the engine?
C++
namespace PlayerGroup
int active_player(int ObjectID, *PlayerNode)
{
blah cold
}
within torquescript, is it possible to do
function PlayerGroup::active_player(this, this)
{
// blah code
return 0; after excute
}
#9
03/31/2008 (5:40 pm)
@Keith: That's the exact purpose of a ConsoleMethod--it exposes C++ code directly to TorqueScript. As the discussion above mentions, you can either write the c++ code itself directly into the ConsoleMethod (which is a pre-processor macro, so has some slightly different syntax, such as "object" instead of "this"), or you can simply use the ConsoleMethod as a wrapper to a normal C++ class method.
#10
Maybe I should also say that I'm a beginner in C++. I took one course on it so I have a little understanding of it, but not a whole lot.
05/23/2008 (2:03 pm)
Is there some better documentation on how to expose C++ functions/methods to TorqueScript? This thread seems like some really good info, but just doesn't quite do it for me in terms of being able to look at these examples and know how to do it with my own code.Maybe I should also say that I'm a beginner in C++. I took one course on it so I have a little understanding of it, but not a whole lot.
#11
This TDN page has a section of console methods:
tdn.garagegames.com/wiki/Code/How_do_I_make_a_scriptable_object%3F
05/23/2008 (2:36 pm)
For the benefit of Deozaan and others, is there a source file that documents the process of creating console functions/methods? I've noticed some great comments in simObject.h and consoleObject.h but haven't run across this yet.This TDN page has a section of console methods:
tdn.garagegames.com/wiki/Code/How_do_I_make_a_scriptable_object%3F
#12
Once again that looks really useful but I'm not sure if that will work for what I'm trying to accomplish.
I'm trying to add a CRC32 hash function to TGB using this source:
www.createwindow.com/programming/crc32/index.htm
I don't think it creates an object. It's just a few functions. I need to be able to call the function from Torquescript, passing a string to convert to the hash.
Incidentally, I'd also like it to return the hash in decimal form instead of hex, so I can use it as a seed for the random number generator. But that's a bit off topic for this particular thread.
05/23/2008 (3:24 pm)
Thanks James,Once again that looks really useful but I'm not sure if that will work for what I'm trying to accomplish.
I'm trying to add a CRC32 hash function to TGB using this source:
www.createwindow.com/programming/crc32/index.htm
I don't think it creates an object. It's just a few functions. I need to be able to call the function from Torquescript, passing a string to convert to the hash.
Incidentally, I'd also like it to return the hash in decimal form instead of hex, so I can use it as a seed for the random number generator. But that's a bit off topic for this particular thread.
#13
All the examples I see go something like this:
But I don't understand what the two integers are for or what they represent. I see them range from 1-4 in the source examples I've looked at.
05/23/2008 (4:04 pm)
I guess what I'm looking for is ConsoleFunctions, not ConsoleMethods.All the examples I see go something like this:
ConsoleFunction(FunctionName, ReturnDataType, int, int, "Description of what this function does")
{
//function here
}But I don't understand what the two integers are for or what they represent. I see them range from 1-4 in the source examples I've looked at.
#14
05/23/2008 (4:07 pm)
They are the min and max arguments that that function can take.
#15
A consoleFunction that takes zero parameters (from script), should be 1/1 (min/max).
A consoleMethod that takes zero parameters (from script), should be 2/2 (min/max).
05/23/2008 (4:24 pm)
They fulfill the same role as the two int parameters of console methods, only subtract 1 from each.A consoleFunction that takes zero parameters (from script), should be 1/1 (min/max).
A consoleMethod that takes zero parameters (from script), should be 2/2 (min/max).
#16
I think my big question now is what if I want the function to return a U32 integer? All I can see is that it will return an integer but I don't see it specifying whether that's U32 or S32.
Also look at Console.cc about line 68 for more information.
05/23/2008 (4:26 pm)
Okay I found some information in console.h in the ConsoleConstructor (about line 612) and more specifically on about line 759.I think my big question now is what if I want the function to return a U32 integer? All I can see is that it will return an integer but I don't see it specifying whether that's U32 or S32.
Also look at Console.cc about line 68 for more information.
#17
05/23/2008 (4:33 pm)
U32 is not an option, use S32 and it will work fine.
#18
I just don't see how S32 will work fine. Please remember I'm a beginner and just sort of stumbling around in the source for answers.
The hash will create a hex value between 0x00000000 and 0xFFFFFFFF, which translates to decimal as being between 0 and 4294967295. Which is perfect for U32. But S32 only goes from -2147483648 to 2147483647. I'm sure you already know this.
So even if the hash will probably be above the range of a S32 integer half of the time, it will be just fine? Will you please explain how that works?
05/23/2008 (6:20 pm)
First of all, let me say thank you very much for all of the help you've provided so far! I just don't see how S32 will work fine. Please remember I'm a beginner and just sort of stumbling around in the source for answers.
The hash will create a hex value between 0x00000000 and 0xFFFFFFFF, which translates to decimal as being between 0 and 4294967295. Which is perfect for U32. But S32 only goes from -2147483648 to 2147483647. I'm sure you already know this.
So even if the hash will probably be above the range of a S32 integer half of the time, it will be just fine? Will you please explain how that works?
#19
05/23/2008 (7:44 pm)
TorqueScript does not differentiate between a signed and an unsigned integer. Are you really sure that you're going to use a number larger than 2 billion?
#20
05/23/2008 (8:30 pm)
Quote:Are you really sure that you're going to use a number larger than 2 billion?I'm just saying that the hash returns a value that is anywhere in the range of an unsigned long integer. I'm not going to specifically choose it, but yes the hash will probably generate a number that is larger than 2 billion at some time or another during its use.
Associate Phillip O'Shea
Violent Tulip
ConsoleMethod (...) { object -> myFunction(myArgs); } void myFunction(...) { do stuff here }I don't think you can explicitly call a console function or method that you create, but if you create a new function which is called my your console function, then it is easily accessed in C++. I hope that is what you were asking.