Jump to content
gc8

Class shared data

Recommended Posts

Hi

I wanted to ask you all how would you solve this programming problem with arma classes that I have.

Here's my code:
 

class State1
  {
   condition = "[_player,""16Rnd_9x21_Mag""] call hasItem";
  };
  class State2
  {
   condition = "([_player,""16Rnd_9x21_Mag""] call hasItem) && (_player distance2d end) < 2";
  };

 

The problem is I don't like when there's duplicated code and would like to have the later condition in form like this:  condition = "State1.condition && (_player distance2d end) < 2";

But as far as I know that's not possible with arma classes, or is it?

 

any suggestions are welcome!

 

Share this post


Link to post
Share on other sites

You could go for something like getting the condition value from Class1 with GetText( configfile >> "yourclass" >> "condition" ), call compile that to evaluate if that is true or false and then combine that with && and your second expression.

  • Confused 1

Share this post


Link to post
Share on other sites

Could always separate each condition to its own property, then only inherit conditions needed and blank out those not needed. Not particularly pretty and could get messy depending on how many states you have and all state would need to be && (without extra config properties). Just an idea to a problem.

//Where commented properties are inherited( there just for example purposes ) 
class State1
{
	condition = "[_player,""16Rnd_9x21_Mag""] call hasItem";
};
class State2 : State1
{
	//condition = "[_player,""16Rnd_9x21_Mag""] call hasItem";
	condition1 = "(_player distance2d end) < 2";
};
class State3 : State2
{
	condition = ""; //Override original condition
	//condition1 = "(_player distance2d end) < 2";
	condition2 = "alive _player";
};
class State4 : State2
{
	//condition = "[_player,""16Rnd_9x21_Mag""] call hasItem";
	//condition1 = "(_player distance2d end) < 2";
	condition2 = "alive _player";
};
//Function and _player for conditions
hasItem = {
	params[ "_unit", "_item" ];
	
	_item in magazines _unit
};
_player = player;

//Get State conditions paths
_conditions = configProperties[ missionConfigFile >> "State1", "configName _x select[ 0, 9 ] == 'condition'" ];
if ( {
	_x params[ "_CfgPath" ];
	
	//Get condition code
	_check = getText( _CfgPath );
	//If its not a blank string
	if !( _check isEqualTo "" ) then {
		//Return compiled result
		call compile _check
	}else{
		//Else treat as true
		true
	};
	//If all true
}count _conditions isEqualTo count _conditions ) then {
	//Do what ever
	_text = "Passed:";
	{
		_text = format[ "%1\n%2", _text, getText( _x ) ];
	}forEach _conditions;
	hint _text;
}else{
	hint "failed";
};

 

  • Like 3

Share this post


Link to post
Share on other sites

First of all there is some philosophical issues to resolve. For instance, what is the truth value of the following states?

class State1 {
    condition = "not State2.condition";
};
class State2 {
    condition = "not State1.condition";  
};

To resolve this, and a lot of other potential problems, my suggestion is to divide it into previous and current values of the condition. We are going to create a variable representing the current value (or status) of each condition. Needs to be global since we can't assign by string otherwise, e.g. using setVariable. Also different syntax since '.' not allowed in global variables. So we might rewrite your condition as, where TAG can be something else of course:

class State1 {
    condition = "[_player,""16Rnd_9x21_Mag""] call hasItem";
};
class State2 {
    condition = "TAG_State1_Status && (_player distance2d end) < 2";
};

So go through each State config before evaluating and:

// First time setup. You have all the classnames, e.g. "State1" and "State2" in TAG_StateConfigNames.
{
    // Create a variable containing the previous value. 
    private _varName = format ["TAG_%1_Status", _x];
    // Assume false in beginning
    missionNameSpace setVariable [_varName, false];
} forEach TAG_StateConfigNames;

Then everytime you evaluate, you use the current values to compute the next values:

// Every time you evaluate
EvaluateStates = {
    private _nextValues = [];
    {
        // Assume you have gotten x.condition into _condition as code here somehow. For example
        private _condition = compile (getText (configFile >> "MyPath" >> _x >> "condition"));
        // Though you probably want to maybe cache the compiling ^^
        private _status = nil call _condition;
        _nextValues pushBack [_x, _status];
    } forEach TAG_StateConfigNames;

    // Update for next iteration the condition values
    {
        missionNameSpace setVariable _x;
    } forEach _nextValues;
};

The side effect of this approach is that any condition depending on another condition is always an evaluation behind.

  • Like 2

Share this post


Link to post
Share on other sites

Thanks for the replies everyone, interesting discussion..

I coded similar solution on the other day than what Larrow did. In my solution each class can define "condition" which is not supposed to be inherited and "conditionNumber" where number is the State Number and this variable will be inherited.

 

So I can do:

 

class State1
{
 condition1 = "[_player,""16Rnd_9x21_Mag""] call hasItem";
};
class State2: State1
{
 condition = "(_player distance2d end) < 2";
   
// or condition2 = for further inheritence
};

 

And the State2 will have both conditions evaluated.

 

 

Edited by gc8
added condition2

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

×