@ -1,55 +1,141 @@
// This code is part of the Fungus library (https://github.com/snozbot/fungus)
// This code is part of the Fungus library (https://github.com/snozbot/fungus)
// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE)
// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE)
using UnityEngine ;
using System.Collections.Generic ;
using System.Collections.Generic ;
using System.Text ;
using UnityEngine ;
namespace Fungus
namespace Fungus
{
{
public abstract class VariableCondition : Condition , ISerializationCallbackReceiver
/// <summary>
/// class for a single condition. A list of this is used for multiple conditions.
/// </summary>
[System.Serializable]
public class ConditionExpression
{
{
[Tooltip("The type of comparison to be performed")]
[SerializeField] protected CompareOperator compareOperator ;
[SerializeField] protected CompareOperator compareOperator ;
[SerializeField] protected AnyVariableAndDataPair anyVar ;
public virtual AnyVariableAndDataPair AnyVar { get { return anyVar ; } }
public virtual CompareOperator CompareOperator { get { return compareOperator ; } }
public ConditionExpression ( )
{
}
public ConditionExpression ( CompareOperator op , AnyVariableAndDataPair variablePair )
{
compareOperator = op ;
anyVar = variablePair ;
}
}
public abstract class VariableCondition : Condition , ISerializationCallbackReceiver
{
public enum AnyOrAll
{
AnyOf_OR , //Use as a chain of ORs
AllOf_AND , //Use as a chain of ANDs
}
[SerializeField] protected AnyVariableAndDataPair anyVar = new AnyVariableAndDataPair ( ) ;
[Tooltip("Selecting AnyOf will result in true if at least one of the conditions is true. Selecting AllOF will result in true only when all the conditions are true.")]
[SerializeField] protected AnyOrAll anyOrAllConditions ;
[SerializeField] protected List < ConditionExpression > conditions = new List < ConditionExpression > ( ) ;
/// <summary>
/// Called when the script is loaded or a value is changed in the
/// inspector (Called in the editor only).
/// </summary>
public override void OnValidate ( )
{
base . OnValidate ( ) ;
if ( conditions = = null )
{
conditions = new List < ConditionExpression > ( ) ;
}
if ( conditions . Count = = 0 )
{
conditions . Add ( new ConditionExpression ( ) ) ;
}
}
protected override bool EvaluateCondition ( )
protected override bool EvaluateCondition ( )
{
{
if ( anyVar . variable = = null )
if ( conditions = = null | | conditions . Count = = 0 )
{
{
return false ;
return false ;
}
}
bool condition = false ;
bool resultAny = false , resultAll = true ;
anyVar . Compare ( compareOperator , ref condition ) ;
foreach ( ConditionExpression condition in conditions )
{
bool curResult = false ;
if ( condition . AnyVar = = null )
{
resultAll & = curResult ;
resultAny | = curResult ;
continue ;
}
condition . AnyVar . Compare ( condition . CompareOperator , ref curResult ) ;
resultAll & = curResult ;
resultAny | = curResult ;
}
return condition ;
if ( anyOrAllConditions = = AnyOrAll . AnyOf_OR ) return resultAny ;
return resultAll ;
}
}
protected override bool HasNeededProperties ( )
protected override bool HasNeededProperties ( )
{
{
return ( anyVar . variable ! = null ) ;
if ( conditions = = null | | conditions . Count = = 0 )
{
return false ;
}
}
#region Public members
foreach ( ConditionExpression condition in conditions )
{
/// <summary>
if ( condition . AnyVar = = null | | condition . AnyVar . variable = = null )
/// The type of comparison operation to be performed.
{
/// </summary>
return false ;
public virtual CompareOperator CompareOperator { get { return compareOperator ; } }
}
}
return true ;
}
public override string GetSummary ( )
public override string GetSummary ( )
{
{
if ( anyVar . variable = = null )
if ( ! this . HasNeededProperties ( ) )
{
{
return "Error: No variable selected" ;
return "Error: No variable selected" ;
}
}
string summary = anyVar . variable . Key + " " ;
string connector = "" ;
summary + = VariableUtil . GetCompareOperatorDescription ( compareOperator ) + " " ;
if ( anyOrAllConditions = = AnyOrAll . AnyOf_OR )
summary + = anyVar . GetDataDescription ( ) ;
{
connector = " <b>OR</b> " ;
}
else
{
connector = " <b>AND</b> " ;
}
StringBuilder summary = new StringBuilder ( "" ) ;
for ( int i = 0 ; i < conditions . Count ; i + + )
{
summary . Append ( conditions [ i ] . AnyVar . variable . Key + " " +
VariableUtil . GetCompareOperatorDescription ( conditions [ i ] . CompareOperator ) + " " +
conditions [ i ] . AnyVar . GetDataDescription ( ) ) ;
return summary ;
if ( i < conditions . Count - 1 )
{
summary . Append ( connector ) ;
}
}
return summary . ToString ( ) ;
}
}
public override bool HasReference ( Variable variable )
public override bool HasReference ( Variable variable )
@ -57,10 +143,14 @@ namespace Fungus
return anyVar . HasReference ( variable ) ;
return anyVar . HasReference ( variable ) ;
}
}
# endregion
#region backwards compat
#region backwards compat
[HideInInspector]
[SerializeField] protected CompareOperator compareOperator ;
[HideInInspector]
[SerializeField] protected AnyVariableAndDataPair anyVar ;
[Tooltip("Variable to use in expression")]
[Tooltip("Variable to use in expression")]
[VariableProperty(AllVariableTypes.VariableAny.Any)]
[VariableProperty(AllVariableTypes.VariableAny.Any)]
@ -120,14 +210,9 @@ namespace Fungus
void ISerializationCallbackReceiver . OnAfterDeserialize ( )
void ISerializationCallbackReceiver . OnAfterDeserialize ( )
{
{
if ( variable = = null )
if ( variable ! = null )
{
return ;
}
else
{
{
anyVar . variable = variable ;
anyVar . variable = variable ;
}
if ( variable . GetType ( ) = = typeof ( BooleanVariable ) & & ! booleanData . Equals ( new BooleanData ( ) ) )
if ( variable . GetType ( ) = = typeof ( BooleanVariable ) & & ! booleanData . Equals ( new BooleanData ( ) ) )
{
{
@ -214,6 +299,22 @@ namespace Fungus
//moved to new anyvar storage, clear legacy.
//moved to new anyvar storage, clear legacy.
variable = null ;
variable = null ;
}
}
# endregion
// just checking for anyVar != null fails here. is any var being reintilaized somewhere?
if ( anyVar ! = null & & anyVar . variable ! = null )
{
ConditionExpression c = new ConditionExpression ( compareOperator , anyVar ) ;
if ( ! conditions . Contains ( c ) )
{
conditions . Add ( c ) ;
}
anyVar = null ;
variable = null ;
}
}
#endregion backwards compat
}
}
}
}