Jump to content
Sign in to follow this  
jaynic

Registering function via description.ext CfgFunctions

Recommended Posts

Hi all,

I'm attempting to re-structure and organize my code - but I am having problems registering my external functions inside the missions description.ext > CfgFunctions class.

I have the following inside the description.ext:

class ohtc
{
tag = "ohtc";

class testCategory
{
	file = "ohtc\f\testCategory";
	class testFunction	{
		description = "This is a test function that returns a silly string";
	};
};
};

I then create the corresponding folder inside the mission root (right next to the description.ext):

ohtc/f/testCategory

Inside there - I have a file called: "fn_testFunction.sqf"

The contents of that file are as follows:

//Return the string with a prependix;
private ["_a"];
_b = _this select 0;
_a = 'passed in: ';

_a + _b;

When I go in game, and enter the following in to the debugger:

hint format ['called my function: %1' , (['asdasd'] call ohtc_fnc_testFunction)];

all I get is a hint that says "called my function: any"

I feel like this is a silly syntax error oversite on my part.. can anyone please assist?

Share this post


Link to post
Share on other sites

You need to put class CfgFunctions { }; around all of your other sub classes in the description.ext

Share this post


Link to post
Share on other sites

What JShock means is that in your Description.ext, your functions stuff has to look like this:

class CfgFunctions
{
   class ohtc
   {
       tag = "ohtc";

       class testCategory
       {
           file = "ohtc\f\testCategory";
           class testFunction    {
               description = "This is a test function that returns a silly string";
           };
       };
   };  
};

But if you want to put in a lot of functions and probably categorize them, you're probably better off putting that code into an external "functions.hpp" file and referencing that inside your Description.ext like that:

class CfgFunctions
{
   #include "functions.hpp"; 
};

Share this post


Link to post
Share on other sites

What is inside fn_testFunction.sqf? You would get an error if it couldnt configure function, so that should be ok.

Share this post


Link to post
Share on other sites
What JShock means is that in your Description.ext' date=' your functions stuff has to look like this:

But if you want to put in a lot of functions and probably categorize them, you're probably better off putting that code into an external "functions.hpp" file and referencing that inside your Description.ext like that:[/quote']

Thanks for that Johnny, was on my phone with limited editing capability :p, and Killzone does have a point, make sure you have the -showScriptErrors enabled.

Share this post


Link to post
Share on other sites

Thanks guys. I totally derped and didn't see that I failed to wrap it in the CfgFunctions class... Sometimes you just need another pair of eyes to see what's right in front of you.

What JShock means is that in your Description.ext' date=' your functions stuff has to look like this:

... you're probably better off putting that code into an external "functions.hpp" file and referencing that inside your Description.ext like that:

class CfgFunctions
{
   #include "functions.hpp"; 
};

[/quote']

So - if I understand what #including an hpp file is - it basically writes the contents of that hpp file in to the body of the containing document at run time? Basically, it will keep the character limits down and permit better organization. Cool.

An architecture question followup:

I come from an object oriented background - so I really prefer the ability to load classes with internal methods. Is there a way to mimic this in the arma scripting language? For example:

//pseudo-code
//filename unitExtension.sqf

//the initial unit that constructed the class
private ["_unit"];
_unit = _this select 0;

getType = {
//return the type
};

isMan = {
 //return a boolean of whether or not this is a man
};

isPlayer = {
 //return Whether or not this is a player unit
};

//presumably this would pass back the whole script?
this;

And then comsume that in some way in another part of the mission say:

//pseudo-code
//filename: someOtherScript.sqf;

myUnit0 = [_myPredefinedSoldier_0] call ohtc_fnc_unitExtension;
myUnit1 = [_myPredefinedSoldier_1] call ohtc_fnc_unitExtension;

//proceed to call functions within the specific unit:
//How could I call something like myUnit0.getType ??

thanks!

Share this post


Link to post
Share on other sites

Yeah, I've figured out that I can construct inline functions. But my question is more along the lines of how I can call the inline functions externally after instantiation of the parent class.

So as per my example above

//pseudo-code 
//filename: someOtherScript.sqf; 

myUnit0 = [_myPredefinedSoldier_0] call ohtc_fnc_unitExtension; 
myUnit1 = [_myPredefinedSoldier_1] call ohtc_fnc_unitExtension; 

//proceed to call functions within the specific unit: 
//How could I call something like myUnit0.getType ??  

How could I call one of the functions inside myUnit0, and myUnit1?

Share this post


Link to post
Share on other sites

You can either execVM your script file, with the funcitons above all the rest of the call lines, so the call lines have something to reference:

//somescript.sqf
//[] execVM "somescript.sqf";

inline_fnc1 =
{
//blah
};

inline_fnc2 =
{
//blah
};

[unit1] call inline_fnc1;
[unit2] call inline_fnc2;

Or you can have an .sqf file with all your inline functions, then in the init.sqf do a:

//init.sqf
call compile preprocessFile "inlineFunctions.sqf";

//inlineFunctions.sqf

inline_fnc1 =
{
//blah
};

inline_fnc2 =
{
//blah
};

inline_fnc3 =
{
//blah
};

Then all these functions you can call anywhere else in any other script.

I hope that's what your asking anyways :p, we may need more context on what you mean by "call one of the functions inside myUnit0, and myUnit1".

Edited by JShock

Share this post


Link to post
Share on other sites

Getting close... let me put it this way.... If this was javascript - I would write it like so:

//pseudo-code
//UnitExtension - this class is constructed around a unit to add commonly used functions for a particular unit
//PARAMETERS: pass in a valid unit
function UnitExtension(pUnit) {
 this.unit = pUnit;

 this.getName = function(){
   return //call some bohemia function to get the units name
 }
 this.isPlayer = function(){
   return //call some bohemia function to get whether or not this is a player
 }
}

Now I have my utility - next I want to comsume this in some fashion... So in some other script:

//pseudo-code
//InitializeUnits - This script will set the units in the mission with some default loadouts - it will not manipulate players loadouts - only AI

_myUnit0 = new UnitExtension(someAiUnit);
_myUnit1 = new UnitExtension(somePlayerUnit);

//Now we determine if we need to adjust the loadouts of the units - ignore players
if(!_myUnit0.isPlayer){
 //This would evaluate to true - because _myUnit0 is an AI unit;
 //Call some function to adjust the loadout
}
if(!_myUnit1.isPlayer) {
 //This wouldn't run - because the function returned true: he is a player
}

Share this post


Link to post
Share on other sites

Something like this then?

ohtc_fnc_unitExtension =
{
_unit = (_this select 0);
_unitIsPlayer = false;

if (isPlayer _unit) then 
{
	_unitIsPlayer = true;
};
[_unit, _unitIsPlayer];//this is the return array for the "call ohtc_fnc_unitExtension"
};

//some other script

myUnit0 = [_myPredefinedSoldier_0] call ohtc_fnc_unitExtension;
//myUnit0 after the function completed would equal: [_myPredefinedSoldier_0, false]
myUnit1 = [_myPredefinedSoldier_1] call ohtc_fnc_unitExtension;
//myUnit1 after the function completed would equal: [_myPredefinedSoldier_1, true]

if !(myUnit0 select 1) then
{
[myUnit0 select 0] execVM "loadout.sqf";
};

if !(myUnit1 select 1) then
{
//do nothing as it is a player
};

Share this post


Link to post
Share on other sites

Ahh I see. So I can only return arrays of data from a script. And to pull out that data, I have to already know what index the desired parameter exists in?

I get it - I don't agree with it because that means all of my logic has to run regardless of whether or not I need to call it... Or - can I return the function itself as an entry in the array?

Thanks for taking all this time to answer BTW - really appreciate it.

Share this post


Link to post
Share on other sites

You could return a function as apart of the return of the ohtc_fnc_unitExtension if you wanted to. I don't see the point in it if you have the functions defined globally though?

But you could also have all these checks as to whether a unit is a player or not, and do the needed stuff within the ohtc_fnc_unitExtension, instead of returning whether or not it's a player or not, but I might not have enough context to see the need for what you are currently doing.

For example, in a script you could just have a unit passed into the ohtc_fnc_unitExtension function, and have the function check if they are AI or not, then just run the loadout script as necessary:

ohtc_fnc_unitExtension =
{
   _unit = (_this select 0);
   _unitIsPlayer = false;

   if !(isPlayer _unit) then 
   {
       [_unit] execVM "loadout.sqf";//if the unit is an AI it will get its loadout
   }
else
{
	_unitIsPlayer = true;
};

_unitIsPlayer;//returns true if the unit is a player, false if AI

};

And if you had a need to use that return in an if statement or something similar:

if ([someUnit] call ohtc_fnc_unitExtension) then {
//do stuff if true
}
else
{
//do other stuff if false
};

Edited by JShock

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×