diff --git a/BehaviorLibrary.sln b/BehaviorLibrary.sln
index 9eed5dd..a6cfc79 100644
--- a/BehaviorLibrary.sln
+++ b/BehaviorLibrary.sln
@@ -1,20 +1,30 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BehaviorLibrary", "BehaviorLibrary\BehaviorLibrary.csproj", "{CC824B6F-6145-485F-9604-FB94F0ECACA7}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {CC824B6F-6145-485F-9604-FB94F0ECACA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {CC824B6F-6145-485F-9604-FB94F0ECACA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {CC824B6F-6145-485F-9604-FB94F0ECACA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {CC824B6F-6145-485F-9604-FB94F0ECACA7}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26020.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BehaviorLibrary", "BehaviorLibrary\BehaviorLibrary.csproj", "{CC824B6F-6145-485F-9604-FB94F0ECACA7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{A7D9F051-A51E-42FF-AD2B-D94DC8A06650}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {CC824B6F-6145-485F-9604-FB94F0ECACA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CC824B6F-6145-485F-9604-FB94F0ECACA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CC824B6F-6145-485F-9604-FB94F0ECACA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CC824B6F-6145-485F-9604-FB94F0ECACA7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A7D9F051-A51E-42FF-AD2B-D94DC8A06650}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A7D9F051-A51E-42FF-AD2B-D94DC8A06650}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A7D9F051-A51E-42FF-AD2B-D94DC8A06650}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(MonoDevelopProperties) = preSolution
+ StartupItem = BehaviorLibrary\BehaviorLibrary.csproj
+ EndGlobalSection
+EndGlobal
diff --git a/BehaviorLibrary/Behavior.cs b/BehaviorLibrary/Behavior.cs
index 8f0b24c..b7102cf 100644
--- a/BehaviorLibrary/Behavior.cs
+++ b/BehaviorLibrary/Behavior.cs
@@ -1,76 +1,81 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using BehaviorLibrary.Components;
-using BehaviorLibrary.Components.Composites;
-
-namespace BehaviorLibrary
-{
- public enum BehaviorReturnCode
- {
- Failure,
- Success,
- Running
- }
-
- public delegate BehaviorReturnCode BehaviorReturn();
-
- ///
- ///
- ///
- public class Behavior
- {
-
- private RootSelector b_Root;
-
- private BehaviorReturnCode b_ReturnCode;
-
- public BehaviorReturnCode ReturnCode
- {
- get { return b_ReturnCode; }
- set { b_ReturnCode = value; }
- }
-
- ///
- ///
- ///
- ///
- public Behavior(RootSelector root)
- {
- b_Root = root;
- }
-
- ///
- /// perform the behavior
- ///
- public BehaviorReturnCode Behave()
- {
- try
- {
- switch (b_Root.Behave())
- {
- case BehaviorReturnCode.Failure:
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- case BehaviorReturnCode.Success:
- ReturnCode = BehaviorReturnCode.Success;
- return ReturnCode;
- case BehaviorReturnCode.Running:
- ReturnCode = BehaviorReturnCode.Running;
- return ReturnCode;
- default:
- ReturnCode = BehaviorReturnCode.Running;
- return ReturnCode;
- }
- }
- catch (Exception e)
- {
-#if DEBUG
- Console.Error.WriteLine(e.ToString());
-#endif
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- }
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using BehaviorLibrary.Components;
+using BehaviorLibrary.Components.Composites;
+
+namespace BehaviorLibrary
+{
+ public enum BehaviorReturnCode
+ {
+ Failure,
+ Success,
+ Running
+ }
+
+ public delegate BehaviorReturnCode BehaviorReturn();
+
+ ///
+ ///
+ ///
+ public class Behavior
+ {
+
+ private BehaviorComponent _Root;
+
+ private BehaviorReturnCode _ReturnCode;
+
+ public BehaviorReturnCode ReturnCode
+ {
+ get { return _ReturnCode; }
+ set { _ReturnCode = value; }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public Behavior(IndexSelector root)
+ {
+ _Root = root;
+ }
+
+ public Behavior(BehaviorComponent root){
+ _Root = root;
+ }
+
+ ///
+ /// perform the behavior
+ ///
+ public BehaviorReturnCode Behave(TreeContext context)
+ {
+ try
+ {
+ switch (_Root.Behave(context))
+ {
+ case BehaviorReturnCode.Failure:
+ ReturnCode = BehaviorReturnCode.Failure;
+ break;
+ case BehaviorReturnCode.Success:
+ ReturnCode = BehaviorReturnCode.Success;
+ break;
+ case BehaviorReturnCode.Running:
+ ReturnCode = BehaviorReturnCode.Running;
+ break;
+ default:
+ ReturnCode = BehaviorReturnCode.Running;
+ break;
+ }
+ }
+ catch (Exception e)
+ {
+#if DEBUG
+ Console.Error.WriteLine(e.ToString());
+#endif
+ ReturnCode = BehaviorReturnCode.Failure;
+ }
+
+ return this.ReturnCode;
+ }
+ }
+}
diff --git a/BehaviorLibrary/BehaviorLibrary.csproj b/BehaviorLibrary/BehaviorLibrary.csproj
index f351907..d098070 100644
--- a/BehaviorLibrary/BehaviorLibrary.csproj
+++ b/BehaviorLibrary/BehaviorLibrary.csproj
@@ -43,19 +43,34 @@
+
-
-
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BehaviorLibrary/Components/Actions/BehaviorAction.cs b/BehaviorLibrary/Components/Actions/BehaviorAction.cs
index f899abe..d536017 100644
--- a/BehaviorLibrary/Components/Actions/BehaviorAction.cs
+++ b/BehaviorLibrary/Components/Actions/BehaviorAction.cs
@@ -1,51 +1,66 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace BehaviorLibrary.Components.Actions
-{
- public class BehaviorAction : BehaviorComponent
- {
-
- private Func ba_Action;
-
- public BehaviorAction() { }
-
- public BehaviorAction(Func action)
- {
- ba_Action = action;
- }
-
- public override BehaviorReturnCode Behave()
- {
- try
- {
- switch (ba_Action.Invoke())
- {
- case BehaviorReturnCode.Success:
- ReturnCode = BehaviorReturnCode.Success;
- return ReturnCode;
- case BehaviorReturnCode.Failure:
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- case BehaviorReturnCode.Running:
- ReturnCode = BehaviorReturnCode.Running;
- return ReturnCode;
- default:
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- }
- }
- catch (Exception e)
- {
-#if DEBUG
- Console.Error.WriteLine(e.ToString());
-#endif
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- }
- }
-
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BehaviorLibrary.Components.Actions
+{
+ public class BehaviorAction : BehaviorComponent
+ {
+
+ private Func _Action;
+ private Func _Action2;
+
+ public BehaviorAction() { }
+
+ public BehaviorAction(Func action)
+ {
+ _Action = action;
+ this.DebugName = action.Method.Name;
+ }
+
+ public BehaviorAction(Func action)
+ {
+ _Action2 = action;
+ this.DebugName = action.Method.Name;
+ }
+
+ public override BehaviorReturnCode OnBehave(TreeContext context)
+ {
+ try
+ {
+ if (this._Action != null)
+ {
+ switch (_Action.Invoke())
+ {
+ case BehaviorReturnCode.Success:
+ ReturnCode = BehaviorReturnCode.Success;
+ return ReturnCode;
+ case BehaviorReturnCode.Failure:
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ case BehaviorReturnCode.Running:
+ ReturnCode = BehaviorReturnCode.Running;
+ return ReturnCode;
+ default:
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ }
+ }
+ else
+ {
+ return _Action2.Invoke(this, context);
+ }
+ }
+ catch (Exception e)
+ {
+#if DEBUG
+ Console.Error.WriteLine(e.ToString());
+#endif
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ }
+ }
+
+ }
+}
diff --git a/BehaviorLibrary/Components/Actions/OnNotCalled.cs b/BehaviorLibrary/Components/Actions/OnNotCalled.cs
new file mode 100644
index 0000000..9f0d417
--- /dev/null
+++ b/BehaviorLibrary/Components/Actions/OnNotCalled.cs
@@ -0,0 +1,45 @@
+namespace BehaviorLibrary.Components.Actions
+{
+ ///
+ /// Provides a way to specifiy behavior for when a behavior is no longer called, due to a different subtree being executed.
+ ///
+ public class OnNotCalled : BehaviorComponent
+ {
+ private BehaviorComponent finalizer;
+ private CallHierarchy lastCallHierarchy;
+ private bool handledThisTick;
+
+ public OnNotCalled(BehaviorComponent finalizer)
+ {
+ this.finalizer = finalizer;
+ }
+
+ public override BehaviorReturnCode OnBehave(TreeContext context)
+ {
+ this.lastCallHierarchy = context.CallingHierarchy;
+ this.handledThisTick = false;
+ context.RegisterOnNotCalledBehavior(this);
+ return BehaviorReturnCode.Success;
+ }
+
+ public bool CanInvokeFinalizer(TreeContext context, BehaviorComponent caller)
+ {
+ if (this.handledThisTick) return true;
+
+ // Check if call hierarchies differ.
+ var currentHierarchy = context.CallingHierarchy;
+ if (context.OldContext != null)
+ {
+ return !currentHierarchy.Matches(context.OldContext.CallingHierarchy);
+ }
+
+ return false;
+ }
+
+ public BehaviorReturnCode InvokeFinalizer(TreeContext context)
+ {
+ this.handledThisTick = true;
+ return this.finalizer.Behave(context);
+ }
+ }
+}
\ No newline at end of file
diff --git a/BehaviorLibrary/Components/BehaviorComponent.cs b/BehaviorLibrary/Components/BehaviorComponent.cs
index ee31e8b..9d0f09e 100644
--- a/BehaviorLibrary/Components/BehaviorComponent.cs
+++ b/BehaviorLibrary/Components/BehaviorComponent.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace BehaviorLibrary.Components
+namespace BehaviorLibrary.Components
{
public abstract class BehaviorComponent
{
@@ -11,6 +6,16 @@ public abstract class BehaviorComponent
public BehaviorComponent() { }
- public abstract BehaviorReturnCode Behave();
+ public string DebugName { get; set; }
+
+ public abstract BehaviorReturnCode OnBehave(TreeContext context);
+
+ public BehaviorReturnCode Behave(TreeContext context)
+ {
+ context.OnAboutToCall(this);
+ this.ReturnCode = this.OnBehave(context);
+ context.OnCalled(this, this.ReturnCode);
+ return this.ReturnCode;
+ }
}
-}
+}
\ No newline at end of file
diff --git a/BehaviorLibrary/Components/CallHierarchy.cs b/BehaviorLibrary/Components/CallHierarchy.cs
new file mode 100644
index 0000000..51255d5
--- /dev/null
+++ b/BehaviorLibrary/Components/CallHierarchy.cs
@@ -0,0 +1,39 @@
+using System.Collections.Generic;
+using System.Linq;
+
+namespace BehaviorLibrary.Components
+{
+ public class CallHierarchy
+ {
+ private IEnumerable callList;
+
+ public CallHierarchy(IEnumerable callList)
+ {
+ this.callList = callList;
+ }
+
+ public bool Matches(CallHierarchy other)
+ {
+ var array = callList.ToArray();
+ var otherArray = other.callList.ToArray();
+ if (array.Length > otherArray.Length) return false; // The current list can be shorter than the old one, because we can still be processing.
+
+ for (int i = 0; i < array.Length; i++)
+ {
+ if (array[i] != otherArray[i])
+ {
+ string oldCallTree = "";
+ otherArray.ToList().ForEach(x => oldCallTree += x.DebugName + System.Environment.NewLine);
+
+ string newCallTree = "";
+ otherArray.ToList().ForEach(x => newCallTree += x.DebugName + System.Environment.NewLine);
+
+ System.Console.Error.WriteLine("Called with {0}, now {1}. Mismatch at {2}", oldCallTree, newCallTree, i);
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/BehaviorLibrary/Components/Composites/BinarySelector.cs b/BehaviorLibrary/Components/Composites/BinarySelector.cs
new file mode 100644
index 0000000..46557a5
--- /dev/null
+++ b/BehaviorLibrary/Components/Composites/BinarySelector.cs
@@ -0,0 +1,33 @@
+using BehaviorLibrary.Components.Conditionals;
+
+namespace BehaviorLibrary.Components.Composites
+{
+ public class BinarySelector : BehaviorComponent
+ {
+ private BehaviorComponent condition;
+ private BehaviorComponent ifTrue;
+ private BehaviorComponent ifFalse;
+
+ public BinarySelector(BehaviorComponent condition, BehaviorComponent ifTrue, BehaviorComponent ifFalse)
+ {
+ this.condition = condition;
+ this.ifTrue = ifTrue;
+ this.ifFalse = ifFalse;
+ }
+
+ public override BehaviorReturnCode OnBehave(TreeContext context)
+ {
+ var result = this.condition.Behave(context);
+ if (result == BehaviorReturnCode.Success)
+ {
+ return this.ifTrue.Behave(context);
+ }
+ else if (result == BehaviorReturnCode.Failure)
+ {
+ return this.ifFalse.Behave(context);
+ }
+
+ return BehaviorReturnCode.Running;
+ }
+ }
+}
\ No newline at end of file
diff --git a/BehaviorLibrary/Components/Composites/ConditionalSelector.cs b/BehaviorLibrary/Components/Composites/ConditionalSelector.cs
new file mode 100644
index 0000000..d596b73
--- /dev/null
+++ b/BehaviorLibrary/Components/Composites/ConditionalSelector.cs
@@ -0,0 +1,50 @@
+using System;
+
+namespace BehaviorLibrary.Components.Composites
+{
+ public class ConditionalSelector : BehaviorComponent
+ {
+ protected BehaviorComponent[] conditions;
+ private BehaviorComponent action;
+
+ public ConditionalSelector(BehaviorComponent condition, BehaviorComponent action)
+ {
+ this.conditions = new BehaviorComponent[] { condition };
+ this.action = action;
+ }
+
+ public ConditionalSelector(BehaviorComponent[] conditions, BehaviorComponent action)
+ {
+ this.conditions = conditions;
+ this.action = action;
+ }
+
+ public override BehaviorReturnCode OnBehave(TreeContext context)
+ {
+ for (int i = 0; i < this.conditions.Length; i++)
+ {
+ try
+ {
+ switch (this.conditions[i].Behave(context))
+ {
+ case BehaviorReturnCode.Failure:
+ return BehaviorReturnCode.Failure;
+ case BehaviorReturnCode.Running:
+ return BehaviorReturnCode.Running;
+ default:
+ continue;
+ }
+ }
+ catch (Exception e)
+ {
+#if DEBUG
+ Console.Error.WriteLine(e.ToString());
+#endif
+ continue;
+ }
+ }
+
+ return this.action.Behave(context);
+ }
+ }
+}
\ No newline at end of file
diff --git a/BehaviorLibrary/Components/Composites/RootSelector.cs b/BehaviorLibrary/Components/Composites/IndexSelector.cs
similarity index 77%
rename from BehaviorLibrary/Components/Composites/RootSelector.cs
rename to BehaviorLibrary/Components/Composites/IndexSelector.cs
index 5c41c4e..eb1894a 100644
--- a/BehaviorLibrary/Components/Composites/RootSelector.cs
+++ b/BehaviorLibrary/Components/Composites/IndexSelector.cs
@@ -1,60 +1,60 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace BehaviorLibrary.Components.Composites
-{
- public class RootSelector : Selector
- {
-
- private BehaviorComponent[] rs_Behaviors;
-
- private Func rs_Index;
-
- ///
- /// The selector for the root node of the behavior tree
- ///
- /// an index representing which of the behavior branches to perform
- /// the behavior branches to be selected from
- public RootSelector(Func index, params BehaviorComponent[] behaviors)
- {
- rs_Index = index;
- rs_Behaviors = behaviors;
- }
-
- ///
- /// performs the given behavior
- ///
- /// the behaviors return code
- public override BehaviorReturnCode Behave()
- {
- try
- {
- switch (rs_Behaviors[rs_Index.Invoke()].Behave())
- {
- case BehaviorReturnCode.Failure:
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- case BehaviorReturnCode.Success:
- ReturnCode = BehaviorReturnCode.Success;
- return ReturnCode;
- case BehaviorReturnCode.Running:
- ReturnCode = BehaviorReturnCode.Running;
- return ReturnCode;
- default:
- ReturnCode = BehaviorReturnCode.Running;
- return ReturnCode;
- }
- }
- catch (Exception e)
- {
-#if DEBUG
- Console.Error.WriteLine(e.ToString());
-#endif
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- }
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BehaviorLibrary.Components.Composites
+{
+ public class IndexSelector : BehaviorComponent
+ {
+
+ private BehaviorComponent[] _Behaviors;
+
+ private Func _Index;
+
+ ///
+ /// The selector for the root node of the behavior tree
+ ///
+ /// an index representing which of the behavior branches to perform
+ /// the behavior branches to be selected from
+ public IndexSelector(Func index, params BehaviorComponent[] behaviors)
+ {
+ _Index = index;
+ _Behaviors = behaviors;
+ }
+
+ ///
+ /// performs the given behavior
+ ///
+ /// the behaviors return code
+ public override BehaviorReturnCode OnBehave(TreeContext context)
+ {
+ try
+ {
+ switch (_Behaviors[_Index.Invoke()].Behave(context))
+ {
+ case BehaviorReturnCode.Failure:
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ case BehaviorReturnCode.Success:
+ ReturnCode = BehaviorReturnCode.Success;
+ return ReturnCode;
+ case BehaviorReturnCode.Running:
+ ReturnCode = BehaviorReturnCode.Running;
+ return ReturnCode;
+ default:
+ ReturnCode = BehaviorReturnCode.Running;
+ return ReturnCode;
+ }
+ }
+ catch (Exception e)
+ {
+#if DEBUG
+ Console.Error.WriteLine(e.ToString());
+#endif
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ }
+ }
+ }
+}
diff --git a/BehaviorLibrary/Components/Composites/ParallelSelector.cs b/BehaviorLibrary/Components/Composites/ParallelSelector.cs
deleted file mode 100644
index 70f1ef0..0000000
--- a/BehaviorLibrary/Components/Composites/ParallelSelector.cs
+++ /dev/null
@@ -1,100 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace BehaviorLibrary.Components.Composites
-{
- public class ParallelSelector : BehaviorComponent
- {
-
- protected BehaviorComponent[] p_Behaviors;
-
- private short p_Selections = 0;
-
- private short p_SelLength = 0;
-
- ///
- /// Selects among the given behavior components
- /// Performs an OR-Like behavior and will "fail-over" to each successive component until Success is reached or Failure is certain
- /// -Returns Success if a behavior component returns Success
- /// -Returns Running if a behavior component returns Running
- /// -Returns Failure if all behavior components returned Failure
- ///
- /// one to many behavior components
- public ParallelSelector(params BehaviorComponent[] behaviors)
- {
- p_Behaviors = behaviors;
- p_SelLength = (short)p_Behaviors.Length;
- }
-
- ///
- /// performs the given behavior
- ///
- /// the behaviors return code
- public override BehaviorReturnCode Behave()
- {
-
- for (int i = 0; i < p_SelLength; i++)
- {
- try
- {
- switch (p_Behaviors[i].Behave())
- {
- case BehaviorReturnCode.Failure:
- continue;
- case BehaviorReturnCode.Success:
- ReturnCode = BehaviorReturnCode.Success;
- return ReturnCode;
- case BehaviorReturnCode.Running:
- ReturnCode = BehaviorReturnCode.Running;
- return ReturnCode;
- default:
- continue;
- }
- }
- catch (Exception e)
- {
-#if DEBUG
- Console.Error.WriteLine(e.ToString());
-#endif
- continue;
- }
- }
-
-
- /*
- while (p_Selections < p_SelLength)
- {
- try
- {
- switch (p_Behaviors[p_Selections].Behave())
- {
- case BehaviorReturnCode.Failure:
- p_Selections++;
- continue;
- case BehaviorReturnCode.Success:
- p_Selections = 0;
- ReturnCode = BehaviorReturnCode.Success;
- return ReturnCode;
- case BehaviorReturnCode.Running:
- ReturnCode = BehaviorReturnCode.Running;
- return ReturnCode;
- default:
- p_Selections++;
- continue;
- }
- }
- catch (Exception)
- {
- p_Selections++;
- continue;
- }
- }*/
-
- p_Selections = 0;
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- }
- }
-}
diff --git a/BehaviorLibrary/Components/Composites/ParallelSequence.cs b/BehaviorLibrary/Components/Composites/ParallelSequence.cs
deleted file mode 100644
index e08dd1f..0000000
--- a/BehaviorLibrary/Components/Composites/ParallelSequence.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace BehaviorLibrary.Components.Composites
-{
- public class ParallelSequence : BehaviorComponent
- {
-
- private BehaviorComponent[] p_Behaviors;
-
- ///
- /// attempts to run the behaviors all in one cycle
- /// -Returns Success when all are successful
- /// -Returns Failure if one behavior fails or an error occurs
- /// -Does not Return Running
- ///
- ///
- public ParallelSequence(params BehaviorComponent[] behaviors)
- {
- p_Behaviors = behaviors;
- }
-
- ///
- /// performs the given behavior
- ///
- /// the behaviors return code
- public override BehaviorReturnCode Behave()
- {
-
- for(int i = 0; i < p_Behaviors.Length;i++)
- {
- try
- {
- switch (p_Behaviors[i].Behave())
- {
- case BehaviorReturnCode.Failure:
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- case BehaviorReturnCode.Success:
- continue;
- case BehaviorReturnCode.Running:
- continue;
- default:
- ReturnCode = BehaviorReturnCode.Success;
- return ReturnCode;
- }
- }
- catch (Exception e)
- {
-#if DEBUG
- Console.Error.WriteLine(e.ToString());
-#endif
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- }
- }
-
- ReturnCode = BehaviorReturnCode.Success;
- return ReturnCode;
- }
-
-
- }
-}
diff --git a/BehaviorLibrary/Components/Composites/PartialSelector.cs b/BehaviorLibrary/Components/Composites/PartialSelector.cs
new file mode 100644
index 0000000..6139e5d
--- /dev/null
+++ b/BehaviorLibrary/Components/Composites/PartialSelector.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BehaviorLibrary.Components.Composites
+{
+ public class PartialSelector : BehaviorComponent
+ {
+
+ protected BehaviorComponent[] _Behaviors;
+
+ private short _selections = 0;
+
+ private short _selLength = 0;
+
+ ///
+ /// Selects among the given behavior components (one evaluation per Behave call)
+ /// Performs an OR-Like behavior and will "fail-over" to each successive component until Success is reached or Failure is certain
+ /// -Returns Success if a behavior component returns Success
+ /// -Returns Running if a behavior component returns Failure or Running
+ /// -Returns Failure if all behavior components returned Failure or an error has occured
+ ///
+ /// one to many behavior components
+ public PartialSelector(params BehaviorComponent[] behaviors)
+ {
+ _Behaviors = behaviors;
+ _selLength = (short)_Behaviors.Length;
+ }
+
+ ///
+ /// performs the given behavior
+ ///
+ /// the behaviors return code
+ public override BehaviorReturnCode OnBehave(TreeContext context)
+ {
+ while (_selections < _selLength)
+ {
+ try
+ {
+ switch (_Behaviors[_selections].Behave(context))
+ {
+ case BehaviorReturnCode.Failure:
+ _selections++;
+ ReturnCode = BehaviorReturnCode.Running;
+ return ReturnCode;
+ case BehaviorReturnCode.Success:
+ _selections = 0;
+ ReturnCode = BehaviorReturnCode.Success;
+ return ReturnCode;
+ case BehaviorReturnCode.Running:
+ ReturnCode = BehaviorReturnCode.Running;
+ return ReturnCode;
+ default:
+ _selections++;
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ }
+ }
+ catch (Exception e)
+ {
+#if DEBUG
+ Console.Error.WriteLine(e.ToString());
+#endif
+ _selections++;
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ }
+ }
+
+ _selections = 0;
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ }
+
+
+ }
+}
diff --git a/BehaviorLibrary/Components/Composites/PartialSequence.cs b/BehaviorLibrary/Components/Composites/PartialSequence.cs
new file mode 100644
index 0000000..e5e14f4
--- /dev/null
+++ b/BehaviorLibrary/Components/Composites/PartialSequence.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BehaviorLibrary.Components.Composites
+{
+ public class PartialSequence : BehaviorComponent
+ {
+
+ protected BehaviorComponent[] _Behaviors;
+
+ private short _sequence = 0;
+
+ private short _seqLength = 0;
+
+ ///
+ /// Performs the given behavior components sequentially (one evaluation per Behave call)
+ /// Performs an AND-Like behavior and will perform each successive component
+ /// -Returns Success if all behavior components return Success
+ /// -Returns Running if an individual behavior component returns Success or Running
+ /// -Returns Failure if a behavior components returns Failure or an error is encountered
+ ///
+ /// one to many behavior components
+ public PartialSequence(params BehaviorComponent[] behaviors)
+ {
+ _Behaviors = behaviors;
+ _seqLength = (short) _Behaviors.Length;
+ }
+
+ ///
+ /// performs the given behavior
+ ///
+ /// the behaviors return code
+ public override BehaviorReturnCode OnBehave(TreeContext context)
+ {
+ //while you can go through them, do so
+ while (_sequence < _seqLength)
+ {
+ try
+ {
+ switch (_Behaviors[_sequence].Behave(context))
+ {
+ case BehaviorReturnCode.Failure:
+ _sequence = 0;
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ case BehaviorReturnCode.Success:
+ _sequence++;
+ ReturnCode = BehaviorReturnCode.Running;
+ return ReturnCode;
+ case BehaviorReturnCode.Running:
+ ReturnCode = BehaviorReturnCode.Running;
+ return ReturnCode;
+ }
+ }
+ catch (Exception e)
+ {
+#if DEBUG
+ Console.Error.WriteLine(e.ToString());
+#endif
+ _sequence = 0;
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ }
+
+ }
+
+ _sequence = 0;
+ ReturnCode = BehaviorReturnCode.Success;
+ return ReturnCode;
+
+ }
+
+ }
+}
diff --git a/BehaviorLibrary/Components/Composites/RandomSelector.cs b/BehaviorLibrary/Components/Composites/RandomSelector.cs
index e2ab30a..805d2ed 100644
--- a/BehaviorLibrary/Components/Composites/RandomSelector.cs
+++ b/BehaviorLibrary/Components/Composites/RandomSelector.cs
@@ -1,64 +1,64 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace BehaviorLibrary.Components.Composites
-{
- public class RandomSelector : BehaviorComponent
- {
-
- private BehaviorComponent[] r_Behaviors;
-
- //use current milliseconds to set random seed
- private Random r_Random = new Random(DateTime.Now.Millisecond);
-
- ///
- /// Randomly selects and performs one of the passed behaviors
- /// -Returns Success if selected behavior returns Success
- /// -Returns Failure if selected behavior returns Failure
- /// -Returns Running if selected behavior returns Running
- ///
- /// one to many behavior components
- public RandomSelector(params BehaviorComponent[] behaviors)
- {
- r_Behaviors = behaviors;
- }
-
- ///
- /// performs the given behavior
- ///
- /// the behaviors return code
- public override BehaviorReturnCode Behave()
- {
- r_Random = new Random(DateTime.Now.Millisecond);
-
- try
- {
- switch (r_Behaviors[r_Random.Next(0, r_Behaviors.Length - 1)].Behave())
- {
- case BehaviorReturnCode.Failure:
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- case BehaviorReturnCode.Success:
- ReturnCode = BehaviorReturnCode.Success;
- return ReturnCode;
- case BehaviorReturnCode.Running:
- ReturnCode = BehaviorReturnCode.Running;
- return ReturnCode;
- default:
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- }
- }
- catch (Exception e)
- {
-#if DEBUG
- Console.Error.WriteLine(e.ToString());
-#endif
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- }
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BehaviorLibrary.Components.Composites
+{
+ public class RandomSelector : BehaviorComponent
+ {
+
+ private BehaviorComponent[] _Behaviors;
+
+ //use current milliseconds to set random seed
+ private Random _Random = new Random(DateTime.Now.Millisecond);
+
+ ///
+ /// Randomly selects and performs one of the passed behaviors
+ /// -Returns Success if selected behavior returns Success
+ /// -Returns Failure if selected behavior returns Failure
+ /// -Returns Running if selected behavior returns Running
+ ///
+ /// one to many behavior components
+ public RandomSelector(params BehaviorComponent[] behaviors)
+ {
+ _Behaviors = behaviors;
+ }
+
+ ///
+ /// performs the given behavior
+ ///
+ /// the behaviors return code
+ public override BehaviorReturnCode OnBehave(TreeContext context)
+ {
+ _Random = new Random(DateTime.Now.Millisecond);
+
+ try
+ {
+ switch (_Behaviors[_Random.Next(0, _Behaviors.Length)].Behave(context))
+ {
+ case BehaviorReturnCode.Failure:
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ case BehaviorReturnCode.Success:
+ ReturnCode = BehaviorReturnCode.Success;
+ return ReturnCode;
+ case BehaviorReturnCode.Running:
+ ReturnCode = BehaviorReturnCode.Running;
+ return ReturnCode;
+ default:
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ }
+ }
+ catch (Exception e)
+ {
+#if DEBUG
+ Console.Error.WriteLine(e.ToString());
+#endif
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ }
+ }
+ }
+}
diff --git a/BehaviorLibrary/Components/Composites/Selector.cs b/BehaviorLibrary/Components/Composites/Selector.cs
index 7f95035..a75d6d1 100644
--- a/BehaviorLibrary/Components/Composites/Selector.cs
+++ b/BehaviorLibrary/Components/Composites/Selector.cs
@@ -1,78 +1,65 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace BehaviorLibrary.Components.Composites
-{
- public class Selector : BehaviorComponent
- {
-
- protected BehaviorComponent[] s_Behaviors;
-
- private short selections = 0;
-
- private short selLength = 0;
-
- ///
- /// Selects among the given behavior components
- /// Performs an OR-Like behavior and will "fail-over" to each successive component until Success is reached or Failure is certain
- /// -Returns Success if a behavior component returns Success
- /// -Returns Running if a behavior component returns Failure or Running
- /// -Returns Failure if all behavior components returned Failure or an error has occured
- ///
- /// one to many behavior components
- public Selector(params BehaviorComponent[] behaviors)
- {
- s_Behaviors = behaviors;
- selLength = (short)s_Behaviors.Length;
- }
-
- ///
- /// performs the given behavior
- ///
- /// the behaviors return code
- public override BehaviorReturnCode Behave()
- {
- while (selections < selLength)
- {
- try
- {
- switch (s_Behaviors[selections].Behave())
- {
- case BehaviorReturnCode.Failure:
- selections++;
- ReturnCode = BehaviorReturnCode.Running;
- return ReturnCode;
- case BehaviorReturnCode.Success:
- selections = 0;
- ReturnCode = BehaviorReturnCode.Success;
- return ReturnCode;
- case BehaviorReturnCode.Running:
- ReturnCode = BehaviorReturnCode.Running;
- return ReturnCode;
- default:
- selections++;
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- }
- }
- catch (Exception e)
- {
-#if DEBUG
- Console.Error.WriteLine(e.ToString());
-#endif
- selections++;
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- }
- }
-
- selections = 0;
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- }
-
-
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BehaviorLibrary.Components.Composites
+{
+ public class Selector : BehaviorComponent
+ {
+
+ protected BehaviorComponent[] _Behaviors;
+
+
+ ///
+ /// Selects among the given behavior components
+ /// Performs an OR-Like behavior and will "fail-over" to each successive component until Success is reached or Failure is certain
+ /// -Returns Success if a behavior component returns Success
+ /// -Returns Running if a behavior component returns Running
+ /// -Returns Failure if all behavior components returned Failure
+ ///
+ /// one to many behavior components
+ public Selector(params BehaviorComponent[] behaviors)
+ {
+ _Behaviors = behaviors;
+ }
+
+ ///
+ /// performs the given behavior
+ ///
+ /// the behaviors return code
+ public override BehaviorReturnCode OnBehave(TreeContext context)
+ {
+
+ for (int i = 0; i < _Behaviors.Length; i++)
+ {
+ try
+ {
+ switch (_Behaviors[i].Behave(context))
+ {
+ case BehaviorReturnCode.Failure:
+ continue;
+ case BehaviorReturnCode.Success:
+ ReturnCode = BehaviorReturnCode.Success;
+ return ReturnCode;
+ case BehaviorReturnCode.Running:
+ ReturnCode = BehaviorReturnCode.Running;
+ return ReturnCode;
+ default:
+ continue;
+ }
+ }
+ catch (Exception e)
+ {
+#if DEBUG
+ Console.Error.WriteLine(e.ToString());
+#endif
+ continue;
+ }
+ }
+
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ }
+ }
+}
diff --git a/BehaviorLibrary/Components/Composites/Sequence.cs b/BehaviorLibrary/Components/Composites/Sequence.cs
index 9f1de9d..de3c36b 100644
--- a/BehaviorLibrary/Components/Composites/Sequence.cs
+++ b/BehaviorLibrary/Components/Composites/Sequence.cs
@@ -1,76 +1,70 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace BehaviorLibrary.Components.Composites
-{
- public class Sequence : BehaviorComponent
- {
-
- protected BehaviorComponent[] s_Behaviors;
-
- private short sequence = 0;
-
- private short seqLength = 0;
-
- ///
- /// Performs the given behavior components sequentially
- /// Performs an AND-Like behavior and will perform each successive component
- /// -Returns Success if all behavior components return Success
- /// -Returns Running if an individual behavior component returns Success or Running
- /// -Returns Failure if a behavior components returns Failure or an error is encountered
- ///
- /// one to many behavior components
- public Sequence(params BehaviorComponent[] behaviors)
- {
- s_Behaviors = behaviors;
- seqLength = (short) s_Behaviors.Length;
- }
-
- ///
- /// performs the given behavior
- ///
- /// the behaviors return code
- public override BehaviorReturnCode Behave()
- {
- //while you can go through them, do so
- while (sequence < seqLength)
- {
- try
- {
- switch (s_Behaviors[sequence].Behave())
- {
- case BehaviorReturnCode.Failure:
- sequence = 0;
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- case BehaviorReturnCode.Success:
- sequence++;
- ReturnCode = BehaviorReturnCode.Running;
- return ReturnCode;
- case BehaviorReturnCode.Running:
- ReturnCode = BehaviorReturnCode.Running;
- return ReturnCode;
- }
- }
- catch (Exception e)
- {
-#if DEBUG
- Console.Error.WriteLine(e.ToString());
-#endif
- sequence = 0;
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- }
-
- }
-
- sequence = 0;
- ReturnCode = BehaviorReturnCode.Success;
- return ReturnCode;
-
- }
-
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BehaviorLibrary.Components.Composites
+{
+ public class Sequence : BehaviorComponent
+ {
+
+ private BehaviorComponent[] _behaviors;
+
+ ///
+ /// attempts to run the behaviors all in one cycle
+ /// -Returns Success when all are successful
+ /// -Returns Failure if one behavior fails or an error occurs
+ /// -Returns Running if any are running
+ ///
+ ///
+ public Sequence(params BehaviorComponent[] behaviors)
+ {
+ _behaviors = behaviors;
+ }
+
+ ///
+ /// performs the given behavior
+ ///
+ /// the behaviors return code
+ public override BehaviorReturnCode OnBehave(TreeContext context)
+ {
+ //add watch for any running behaviors
+ bool anyRunning = false;
+
+ for(int i = 0; i < _behaviors.Length;i++)
+ {
+ try
+ {
+ switch (_behaviors[i].Behave(context))
+ {
+ case BehaviorReturnCode.Failure:
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ case BehaviorReturnCode.Success:
+ continue;
+ case BehaviorReturnCode.Running:
+ anyRunning = true;
+ continue;
+ default:
+ ReturnCode = BehaviorReturnCode.Success;
+ return ReturnCode;
+ }
+ }
+ catch (Exception e)
+ {
+#if DEBUG
+ Console.Error.WriteLine(e.ToString());
+#endif
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ }
+ }
+
+ //if none running, return success, otherwise return running
+ ReturnCode = !anyRunning ? BehaviorReturnCode.Success : BehaviorReturnCode.Running;
+ return ReturnCode;
+ }
+
+
+ }
+}
diff --git a/BehaviorLibrary/Components/Composites/StatefulSelector.cs b/BehaviorLibrary/Components/Composites/StatefulSelector.cs
new file mode 100644
index 0000000..6afa664
--- /dev/null
+++ b/BehaviorLibrary/Components/Composites/StatefulSelector.cs
@@ -0,0 +1,59 @@
+using System;
+using BehaviorLibrary.Components;
+
+namespace BehaviorLibrary
+{
+ public class StatefulSelector : BehaviorComponent
+ {
+ private BehaviorComponent[] _Behaviors;
+
+ private int _LastBehavior = 0;
+
+ ///
+ /// Selects among the given behavior components (stateful on running)
+ /// Performs an OR-Like behavior and will "fail-over" to each successive component until Success is reached or Failure is certain
+ /// -Returns Success if a behavior component returns Success
+ /// -Returns Running if a behavior component returns Running
+ /// -Returns Failure if all behavior components returned Failure
+ ///
+ /// one to many behavior components
+ public StatefulSelector(params BehaviorComponent[] behaviors){
+ this._Behaviors = behaviors;
+ }
+
+ ///
+ /// performs the given behavior
+ ///
+ /// the behaviors return code
+ public override BehaviorReturnCode OnBehave(TreeContext context) {
+
+ for(; _LastBehavior < _Behaviors.Length; _LastBehavior++){
+ try{
+ switch (_Behaviors[_LastBehavior].Behave(context)){
+ case BehaviorReturnCode.Failure:
+ continue;
+ case BehaviorReturnCode.Success:
+ _LastBehavior = 0;
+ ReturnCode = BehaviorReturnCode.Success;
+ return ReturnCode;
+ case BehaviorReturnCode.Running:
+ ReturnCode = BehaviorReturnCode.Running;
+ return ReturnCode;
+ default:
+ continue;
+ }
+ }
+ catch (Exception e){
+#if DEBUG
+ Console.Error.WriteLine(e.ToString());
+#endif
+ continue;
+ }
+ }
+
+ _LastBehavior = 0;
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ }
+ }
+}
diff --git a/BehaviorLibrary/Components/Composites/StatefulSequence.cs b/BehaviorLibrary/Components/Composites/StatefulSequence.cs
new file mode 100644
index 0000000..da69638
--- /dev/null
+++ b/BehaviorLibrary/Components/Composites/StatefulSequence.cs
@@ -0,0 +1,66 @@
+using System;
+using BehaviorLibrary.Components;
+
+namespace BehaviorLibrary
+{
+ public class StatefulSequence : BehaviorComponent
+ {
+ private BehaviorComponent[] _Behaviors;
+
+ private int _LastBehavior = 0;
+
+ ///
+ /// attempts to run the behaviors all in one cycle (stateful on running)
+ /// -Returns Success when all are successful
+ /// -Returns Failure if one behavior fails or an error occurs
+ /// -Does not Return Running
+ ///
+ ///
+ public StatefulSequence (params BehaviorComponent[] behaviors){
+ this._Behaviors = behaviors;
+ }
+
+ ///
+ /// performs the given behavior
+ ///
+ /// the behaviors return code
+ public override BehaviorReturnCode OnBehave(TreeContext context) {
+
+ //start from last remembered position
+ for(; _LastBehavior < _Behaviors.Length;_LastBehavior++){
+ try{
+ switch (_Behaviors[_LastBehavior].Behave(context)){
+ case BehaviorReturnCode.Failure:
+ _LastBehavior = 0;
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ case BehaviorReturnCode.Success:
+ continue;
+ case BehaviorReturnCode.Running:
+ ReturnCode = BehaviorReturnCode.Running;
+ return ReturnCode;
+ default:
+ _LastBehavior = 0;
+ ReturnCode = BehaviorReturnCode.Success;
+ return ReturnCode;
+ }
+ }
+ catch (Exception e){
+#if DEBUG
+ Console.Error.WriteLine(e.ToString());
+#endif
+ _LastBehavior = 0;
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ }
+ }
+
+ _LastBehavior = 0;
+ ReturnCode = BehaviorReturnCode.Success;
+ return ReturnCode;
+ }
+
+
+ }
+}
+
diff --git a/BehaviorLibrary/Components/Conditionals/Conditional.cs b/BehaviorLibrary/Components/Conditionals/Conditional.cs
index db79631..f663353 100644
--- a/BehaviorLibrary/Components/Conditionals/Conditional.cs
+++ b/BehaviorLibrary/Components/Conditionals/Conditional.cs
@@ -1,56 +1,56 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace BehaviorLibrary.Components.Conditionals
-{
- public class Conditional : BehaviorComponent
- {
-
- private Func c_Bool;
-
- ///
- /// Returns a return code equivalent to the test
- /// -Returns Success if true
- /// -Returns Failure if false
- ///
- /// the value to be tested
- public Conditional(Func test)
- {
- c_Bool = test;
- }
-
- ///
- /// performs the given behavior
- ///
- /// the behaviors return code
- public override BehaviorReturnCode Behave()
- {
-
- try
- {
- switch (c_Bool.Invoke())
- {
- case true:
- ReturnCode = BehaviorReturnCode.Success;
- return ReturnCode;
- case false:
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- default:
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- }
- }
- catch (Exception e)
- {
-#if DEBUG
- Console.Error.WriteLine(e.ToString());
-#endif
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- }
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BehaviorLibrary.Components.Conditionals
+{
+ public class Conditional : BehaviorComponent
+ {
+
+ private Func _Bool;
+
+ ///
+ /// Returns a return code equivalent to the test
+ /// -Returns Success if true
+ /// -Returns Failure if false
+ ///
+ /// the value to be tested
+ public Conditional(Func test)
+ {
+ _Bool = test;
+ }
+
+ ///
+ /// performs the given behavior
+ ///
+ /// the behaviors return code
+ public override BehaviorReturnCode OnBehave(TreeContext context)
+ {
+
+ try
+ {
+ switch (_Bool.Invoke())
+ {
+ case true:
+ ReturnCode = BehaviorReturnCode.Success;
+ return ReturnCode;
+ case false:
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ default:
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ }
+ }
+ catch (Exception e)
+ {
+#if DEBUG
+ Console.Error.WriteLine(e.ToString());
+#endif
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ }
+ }
+ }
+}
diff --git a/BehaviorLibrary/Components/Decorators/Awaiter.cs b/BehaviorLibrary/Components/Decorators/Awaiter.cs
new file mode 100644
index 0000000..e259e7f
--- /dev/null
+++ b/BehaviorLibrary/Components/Decorators/Awaiter.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BehaviorLibrary.Components.Decorators
+{
+ public class Awaiter : BehaviorComponent
+ {
+ private Func condition;
+ private BehaviorComponent behavior;
+
+ ///
+ /// executes the behavior after a condition is true.
+ ///
+ /// the condition
+ /// behavior to run
+ public Awaiter(Func conditon, BehaviorComponent behavior)
+ {
+ this.condition = conditon;
+ this.behavior = behavior;
+ }
+
+ ///
+ /// performs the given behavior
+ ///
+ /// the behaviors return code
+ public override BehaviorReturnCode OnBehave(TreeContext context)
+ {
+ try
+ {
+ if (this.condition.Invoke())
+ {
+ return this.behavior.Behave(context);
+ }
+ else
+ {
+ return BehaviorReturnCode.Running;
+ }
+ }
+ catch (Exception e)
+ {
+#if DEBUG
+ Console.Error.WriteLine(e.ToString());
+#endif
+ return BehaviorReturnCode.Failure;
+ }
+ }
+ }
+}
diff --git a/BehaviorLibrary/Components/Decorators/Counter.cs b/BehaviorLibrary/Components/Decorators/Counter.cs
index a51f377..fa93a53 100644
--- a/BehaviorLibrary/Components/Decorators/Counter.cs
+++ b/BehaviorLibrary/Components/Decorators/Counter.cs
@@ -1,59 +1,59 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace BehaviorLibrary.Components.Decorators
-{
- public class Counter : BehaviorComponent
- {
- private int c_MaxCount;
- private int c_Counter = 0;
-
- private BehaviorComponent c_Behavior;
-
- ///
- /// executes the behavior based on a counter
- /// -each time Counter is called the counter increments by 1
- /// -Counter executes the behavior when it reaches the supplied maxCount
- ///
- /// max number to count to
- /// behavior to run
- public Counter(int maxCount, BehaviorComponent behavior)
- {
- c_MaxCount = maxCount;
- c_Behavior = behavior;
- }
-
- ///
- /// performs the given behavior
- ///
- /// the behaviors return code
- public override BehaviorReturnCode Behave()
- {
- try
- {
- if (c_Counter < c_MaxCount)
- {
- c_Counter++;
- ReturnCode = BehaviorReturnCode.Running;
- return BehaviorReturnCode.Running;
- }
- else
- {
- c_Counter = 0;
- ReturnCode = c_Behavior.Behave();
- return ReturnCode;
- }
- }
- catch (Exception e)
- {
-#if DEBUG
- Console.Error.WriteLine(e.ToString());
-#endif
- ReturnCode = BehaviorReturnCode.Failure;
- return BehaviorReturnCode.Failure;
- }
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BehaviorLibrary.Components.Decorators
+{
+ public class Counter : BehaviorComponent
+ {
+ private int _MaxCount;
+ private int _Counter = 0;
+
+ private BehaviorComponent _Behavior;
+
+ ///
+ /// executes the behavior based on a counter
+ /// -each time Counter is called the counter increments by 1
+ /// -Counter executes the behavior when it reaches the supplied maxCount
+ ///
+ /// max number to count to
+ /// behavior to run
+ public Counter(int maxCount, BehaviorComponent behavior)
+ {
+ _MaxCount = maxCount;
+ _Behavior = behavior;
+ }
+
+ ///
+ /// performs the given behavior
+ ///
+ /// the behaviors return code
+ public override BehaviorReturnCode OnBehave(TreeContext context)
+ {
+ try
+ {
+ if (_Counter < _MaxCount)
+ {
+ _Counter++;
+ ReturnCode = BehaviorReturnCode.Running;
+ return BehaviorReturnCode.Running;
+ }
+ else
+ {
+ _Counter = 0;
+ ReturnCode = _Behavior.Behave(context);
+ return ReturnCode;
+ }
+ }
+ catch (Exception e)
+ {
+#if DEBUG
+ Console.Error.WriteLine(e.ToString());
+#endif
+ ReturnCode = BehaviorReturnCode.Failure;
+ return BehaviorReturnCode.Failure;
+ }
+ }
+ }
+}
diff --git a/BehaviorLibrary/Components/Decorators/Failer.cs b/BehaviorLibrary/Components/Decorators/Failer.cs
new file mode 100644
index 0000000..c326ed4
--- /dev/null
+++ b/BehaviorLibrary/Components/Decorators/Failer.cs
@@ -0,0 +1,31 @@
+namespace BehaviorLibrary.Components.Decorators
+{
+ public class Failer : BehaviorComponent
+ {
+ private BehaviorComponent behavior;
+
+ ///
+ /// Returns a failure even when the decorated component succeeded or is running.
+ ///
+ /// behavior to run
+ public Failer(BehaviorComponent behavior)
+ {
+ this.behavior = behavior;
+ }
+
+ ///
+ /// performs the given behavior
+ ///
+ /// the behaviors return code
+ public override BehaviorReturnCode OnBehave(TreeContext context)
+ {
+ this.ReturnCode = behavior.Behave(context);
+ if (this.ReturnCode == BehaviorReturnCode.Success || this.ReturnCode == BehaviorReturnCode.Running)
+ {
+ this.ReturnCode = BehaviorReturnCode.Failure;
+ }
+
+ return this.ReturnCode;
+ }
+ }
+}
diff --git a/BehaviorLibrary/Components/Decorators/Inverter.cs b/BehaviorLibrary/Components/Decorators/Inverter.cs
index 1a75f74..c7ad72b 100644
--- a/BehaviorLibrary/Components/Decorators/Inverter.cs
+++ b/BehaviorLibrary/Components/Decorators/Inverter.cs
@@ -1,61 +1,61 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace BehaviorLibrary.Components.Decorators
-{
- public class Inverter : BehaviorComponent
- {
-
- private BehaviorComponent d_Behavior;
-
- ///
- /// inverts the given behavior
- /// -Returns Success on Failure or Error
- /// -Returns Failure on Success
- /// -Returns Running on Running
- ///
- ///
- public Inverter(BehaviorComponent behavior)
- {
- d_Behavior = behavior;
- }
-
- ///
- /// performs the given behavior
- ///
- /// the behaviors return code
- public override BehaviorReturnCode Behave()
- {
- try
- {
- switch (d_Behavior.Behave())
- {
- case BehaviorReturnCode.Failure:
- ReturnCode = BehaviorReturnCode.Success;
- return ReturnCode;
- case BehaviorReturnCode.Success:
- ReturnCode = BehaviorReturnCode.Failure;
- return ReturnCode;
- case BehaviorReturnCode.Running:
- ReturnCode = BehaviorReturnCode.Running;
- return ReturnCode;
- }
- }
- catch (Exception e)
- {
-#if DEBUG
- Console.Error.WriteLine(e.ToString());
-#endif
- ReturnCode = BehaviorReturnCode.Success;
- return ReturnCode;
- }
-
- ReturnCode = BehaviorReturnCode.Success;
- return ReturnCode;
-
- }
-
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BehaviorLibrary.Components.Decorators
+{
+ public class Inverter : BehaviorComponent
+ {
+
+ private BehaviorComponent _Behavior;
+
+ ///
+ /// inverts the given behavior
+ /// -Returns Success on Failure or Error
+ /// -Returns Failure on Success
+ /// -Returns Running on Running
+ ///
+ ///
+ public Inverter(BehaviorComponent behavior)
+ {
+ _Behavior = behavior;
+ }
+
+ ///
+ /// performs the given behavior
+ ///
+ /// the behaviors return code
+ public override BehaviorReturnCode OnBehave(TreeContext context)
+ {
+ try
+ {
+ switch (_Behavior.Behave(context))
+ {
+ case BehaviorReturnCode.Failure:
+ ReturnCode = BehaviorReturnCode.Success;
+ return ReturnCode;
+ case BehaviorReturnCode.Success:
+ ReturnCode = BehaviorReturnCode.Failure;
+ return ReturnCode;
+ case BehaviorReturnCode.Running:
+ ReturnCode = BehaviorReturnCode.Running;
+ return ReturnCode;
+ }
+ }
+ catch (Exception e)
+ {
+#if DEBUG
+ Console.Error.WriteLine(e.ToString());
+#endif
+ ReturnCode = BehaviorReturnCode.Success;
+ return ReturnCode;
+ }
+
+ ReturnCode = BehaviorReturnCode.Success;
+ return ReturnCode;
+
+ }
+
+ }
+}
diff --git a/BehaviorLibrary/Components/Decorators/RandomDecorator.cs b/BehaviorLibrary/Components/Decorators/RandomDecorator.cs
index 4273243..e65fd4f 100644
--- a/BehaviorLibrary/Components/Decorators/RandomDecorator.cs
+++ b/BehaviorLibrary/Components/Decorators/RandomDecorator.cs
@@ -1,56 +1,56 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace BehaviorLibrary.Components.Decorators
-{
- public class RandomDecorator : BehaviorComponent
- {
-
- private float r_Probability;
-
- private Func r_RandomFunction;
-
- private BehaviorComponent r_Behavior;
-
- ///
- /// randomly executes the behavior
- ///
- /// probability of execution
- /// function that determines probability to execute
- /// behavior to execute
- public RandomDecorator(float probability, Func randomFunction, BehaviorComponent behavior)
- {
- r_Probability = probability;
- r_RandomFunction = randomFunction;
- r_Behavior = behavior;
- }
-
-
- public override BehaviorReturnCode Behave()
- {
- try
- {
- if (r_RandomFunction.Invoke() <= r_Probability)
- {
- ReturnCode = r_Behavior.Behave();
- return ReturnCode;
- }
- else
- {
- ReturnCode = BehaviorReturnCode.Running;
- return BehaviorReturnCode.Running;
- }
- }
- catch (Exception e)
- {
-#if DEBUG
- Console.Error.WriteLine(e.ToString());
-#endif
- ReturnCode = BehaviorReturnCode.Failure;
- return BehaviorReturnCode.Failure;
- }
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BehaviorLibrary.Components.Decorators
+{
+ public class RandomDecorator : BehaviorComponent
+ {
+
+ private float _Probability;
+
+ private Func _RandomFunction;
+
+ private BehaviorComponent _Behavior;
+
+ ///
+ /// randomly executes the behavior
+ ///
+ /// probability of execution
+ /// function that determines probability to execute
+ /// behavior to execute
+ public RandomDecorator(float probability, Func randomFunction, BehaviorComponent behavior)
+ {
+ _Probability = probability;
+ _RandomFunction = randomFunction;
+ _Behavior = behavior;
+ }
+
+
+ public override BehaviorReturnCode OnBehave(TreeContext context)
+ {
+ try
+ {
+ if (_RandomFunction.Invoke() <= _Probability)
+ {
+ ReturnCode = _Behavior.Behave(context);
+ return ReturnCode;
+ }
+ else
+ {
+ ReturnCode = BehaviorReturnCode.Running;
+ return BehaviorReturnCode.Running;
+ }
+ }
+ catch (Exception e)
+ {
+#if DEBUG
+ Console.Error.WriteLine(e.ToString());
+#endif
+ ReturnCode = BehaviorReturnCode.Failure;
+ return BehaviorReturnCode.Failure;
+ }
+ }
+ }
+}
diff --git a/BehaviorLibrary/Components/Decorators/RepeatUntilFail.cs b/BehaviorLibrary/Components/Decorators/RepeatUntilFail.cs
new file mode 100644
index 0000000..be406d3
--- /dev/null
+++ b/BehaviorLibrary/Components/Decorators/RepeatUntilFail.cs
@@ -0,0 +1,41 @@
+using System;
+using BehaviorLibrary;
+using BehaviorLibrary.Components;
+using BehaviorLibrary.Components.Composites;
+using BehaviorLibrary.Components.Actions;
+using BehaviorLibrary.Components.Conditionals;
+using BehaviorLibrary.Components.Decorators;
+using BehaviorLibrary.Components.Utility;
+
+namespace BehaviorLibrary.Components.Decorators
+{
+ public class RepeatUntilFail : BehaviorComponent
+ {
+ private BehaviorComponent _Behavior;
+
+ ///
+ /// executes the behavior every time again
+ ///
+ /// maximum time to wait before executing behavior
+ /// behavior to run
+ public RepeatUntilFail(BehaviorComponent behavior)
+ {
+ _Behavior = behavior;
+ }
+
+ ///
+ /// performs the given behavior
+ ///
+ /// the behaviors return code
+ public override BehaviorReturnCode OnBehave(TreeContext context)
+ {
+ ReturnCode = _Behavior.Behave(context);
+ if (ReturnCode == BehaviorReturnCode.Failure) {
+ return BehaviorReturnCode.Failure;
+ } else {
+ ReturnCode = BehaviorReturnCode.Running;
+ return BehaviorReturnCode.Running;
+ }
+ }
+ }
+}
diff --git a/BehaviorLibrary/Components/Decorators/Repeater.cs b/BehaviorLibrary/Components/Decorators/Repeater.cs
new file mode 100644
index 0000000..404ea19
--- /dev/null
+++ b/BehaviorLibrary/Components/Decorators/Repeater.cs
@@ -0,0 +1,37 @@
+using System;
+using BehaviorLibrary;
+using BehaviorLibrary.Components;
+using BehaviorLibrary.Components.Composites;
+using BehaviorLibrary.Components.Actions;
+using BehaviorLibrary.Components.Conditionals;
+using BehaviorLibrary.Components.Decorators;
+using BehaviorLibrary.Components.Utility;
+
+namespace BehaviorLibrary.Components.Decorators
+{
+ public class Repeater : BehaviorComponent
+ {
+ private BehaviorComponent _Behavior;
+
+ ///
+ /// executes the behavior every time again
+ ///
+ /// maximum time to wait before executing behavior
+ /// behavior to run
+ public Repeater(BehaviorComponent behavior)
+ {
+ _Behavior = behavior;
+ }
+
+ ///
+ /// performs the given behavior
+ ///
+ /// the behaviors return code
+ public override BehaviorReturnCode OnBehave(TreeContext context)
+ {
+ ReturnCode = _Behavior.Behave(context);
+ ReturnCode = BehaviorReturnCode.Running;
+ return BehaviorReturnCode.Running;
+ }
+ }
+}
diff --git a/BehaviorLibrary/Components/Decorators/Succeeder.cs b/BehaviorLibrary/Components/Decorators/Succeeder.cs
new file mode 100644
index 0000000..991ca54
--- /dev/null
+++ b/BehaviorLibrary/Components/Decorators/Succeeder.cs
@@ -0,0 +1,38 @@
+using System;
+using BehaviorLibrary;
+using BehaviorLibrary.Components;
+using BehaviorLibrary.Components.Composites;
+using BehaviorLibrary.Components.Actions;
+using BehaviorLibrary.Components.Conditionals;
+using BehaviorLibrary.Components.Decorators;
+using BehaviorLibrary.Components.Utility;
+
+namespace BehaviorLibrary.Components.Decorators
+{
+ public class Succeeder : BehaviorComponent
+ {
+ private BehaviorComponent _Behavior;
+
+ ///
+ /// returns a success even when the decorated component failed
+ ///
+ /// behavior to run
+ public Succeeder(BehaviorComponent behavior)
+ {
+ _Behavior = behavior;
+ }
+
+ ///
+ /// performs the given behavior
+ ///
+ /// the behaviors return code
+ public override BehaviorReturnCode OnBehave(TreeContext context)
+ {
+ ReturnCode = _Behavior.Behave(context);
+ if (ReturnCode == BehaviorReturnCode.Failure) {
+ ReturnCode = BehaviorReturnCode.Success;
+ }
+ return ReturnCode;
+ }
+ }
+}
diff --git a/BehaviorLibrary/Components/Decorators/Timer.cs b/BehaviorLibrary/Components/Decorators/Timer.cs
index 7004dc8..8f76961 100644
--- a/BehaviorLibrary/Components/Decorators/Timer.cs
+++ b/BehaviorLibrary/Components/Decorators/Timer.cs
@@ -1,64 +1,64 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace BehaviorLibrary.Components.Decorators
-{
- public class Timer : BehaviorComponent
- {
-
- private Func t_ElapsedTimeFunction;
-
- private BehaviorComponent t_Behavior;
-
- private int t_TimeElapsed = 0;
-
- private int t_WaitTime;
-
- ///
- /// executes the behavior after a given amount of time in miliseconds has passed
- ///
- /// function that returns elapsed time
- /// maximum time to wait before executing behavior
- /// behavior to run
- public Timer(Func elapsedTimeFunction, int timeToWait, BehaviorComponent behavior)
- {
- t_ElapsedTimeFunction = elapsedTimeFunction;
- t_Behavior = behavior;
- t_WaitTime = timeToWait;
- }
-
- ///
- /// performs the given behavior
- ///
- /// the behaviors return code
- public override BehaviorReturnCode Behave()
- {
- try
- {
- t_TimeElapsed += t_ElapsedTimeFunction.Invoke();
-
- if (t_TimeElapsed >= t_WaitTime)
- {
- t_TimeElapsed = 0;
- ReturnCode = t_Behavior.Behave();
- return ReturnCode;
- }
- else
- {
- ReturnCode = BehaviorReturnCode.Running;
- return BehaviorReturnCode.Running;
- }
- }
- catch (Exception e)
- {
-#if DEBUG
- Console.Error.WriteLine(e.ToString());
-#endif
- ReturnCode = BehaviorReturnCode.Failure;
- return BehaviorReturnCode.Failure;
- }
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BehaviorLibrary.Components.Decorators
+{
+ public class Timer : BehaviorComponent
+ {
+
+ private Func _ElapsedTimeFunction;
+
+ private BehaviorComponent _Behavior;
+
+ private int _TimeElapsed = 0;
+
+ private int _WaitTime;
+
+ ///
+ /// executes the behavior after a given amount of time in miliseconds has passed
+ ///
+ /// function that returns elapsed time
+ /// maximum time to wait before executing behavior
+ /// behavior to run
+ public Timer(Func elapsedTimeFunction, int timeToWait, BehaviorComponent behavior)
+ {
+ _ElapsedTimeFunction = elapsedTimeFunction;
+ _Behavior = behavior;
+ _WaitTime = timeToWait;
+ }
+
+ ///
+ /// performs the given behavior
+ ///
+ /// the behaviors return code
+ public override BehaviorReturnCode OnBehave(TreeContext context)
+ {
+ try
+ {
+ _TimeElapsed += _ElapsedTimeFunction.Invoke();
+
+ if (_TimeElapsed >= _WaitTime)
+ {
+ _TimeElapsed = 0;
+ ReturnCode = _Behavior.Behave(context);
+ return ReturnCode;
+ }
+ else
+ {
+ ReturnCode = BehaviorReturnCode.Running;
+ return BehaviorReturnCode.Running;
+ }
+ }
+ catch (Exception e)
+ {
+#if DEBUG
+ Console.Error.WriteLine(e.ToString());
+#endif
+ ReturnCode = BehaviorReturnCode.Failure;
+ return BehaviorReturnCode.Failure;
+ }
+ }
+ }
+}
diff --git a/BehaviorLibrary/Components/Utility/UtilityPair.cs b/BehaviorLibrary/Components/Utility/UtilityPair.cs
new file mode 100644
index 0000000..25edc05
--- /dev/null
+++ b/BehaviorLibrary/Components/Utility/UtilityPair.cs
@@ -0,0 +1,39 @@
+//
+// UtilityPair.cs
+//
+// Author:
+// Thomas H. Jonell <@Net_Gnome>
+//
+// Copyright (c) 2014 Thomas H. Jonell
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program. If not, see .
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BehaviorLibrary.Components.Utility
+{
+ public class UtilityPair
+ {
+ public UtilityPair(UtilityVector vector, BehaviorComponent behavior)
+ {
+ this.vector = vector;
+ this.behavior = behavior;
+ }
+
+ public UtilityVector vector { get; set; }
+ public BehaviorComponent behavior { get; set; }
+ }
+}
diff --git a/BehaviorLibrary/Components/Utility/UtilitySelector.cs b/BehaviorLibrary/Components/Utility/UtilitySelector.cs
new file mode 100644
index 0000000..57780bf
--- /dev/null
+++ b/BehaviorLibrary/Components/Utility/UtilitySelector.cs
@@ -0,0 +1,77 @@
+//
+// UtilitySelector.cs
+//
+// Author:
+// Thomas H. Jonell <@Net_Gnome>
+//
+// Copyright (c) 2014 Thomas H. Jonell
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program. If not, see .
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BehaviorLibrary.Components.Utility
+{
+ public class UtilitySelector : BehaviorComponent
+ {
+ private UtilityPair[] _utility_pairs;
+ private Func _utility_function;
+
+ public UtilitySelector(Func utility_function, params UtilityPair[] pairs)
+ {
+ this._utility_pairs = pairs;
+ this._utility_function = utility_function;
+ }
+
+ public override BehaviorReturnCode OnBehave(TreeContext context)
+ {
+ try{
+ UtilityVector func_vector = this._utility_function.Invoke ();
+
+ float min = -2.0f;
+ UtilityPair best_match = null;
+
+ //find max pair match
+ foreach(UtilityPair pair in this._utility_pairs){
+ float val = func_vector.dot(pair.vector);
+ if(val > min){
+ min = val;
+ best_match = pair;
+ }
+ }
+
+ //make sure we found a match
+ if(best_match == null){
+ #if DEBUG
+ Console.WriteLine("best_match not defined...");
+ #endif
+ this.ReturnCode = BehaviorReturnCode.Failure;
+ return this.ReturnCode;
+ }
+
+ //execute best pair match and return result
+ this.ReturnCode = best_match.behavior.Behave(context);
+ return this.ReturnCode;
+ }catch(Exception e){
+ #if DEBUG
+ Console.WriteLine(e.ToString());
+ #endif
+ this.ReturnCode = BehaviorReturnCode.Failure;
+ return BehaviorReturnCode.Failure;
+ }
+ }
+ }
+}
diff --git a/BehaviorLibrary/Components/Utility/UtilityVector.cs b/BehaviorLibrary/Components/Utility/UtilityVector.cs
new file mode 100644
index 0000000..aed7248
--- /dev/null
+++ b/BehaviorLibrary/Components/Utility/UtilityVector.cs
@@ -0,0 +1,85 @@
+//
+// UtilityVector.cs
+//
+// Author:
+// Thomas H. Jonell <@Net_Gnome>
+//
+// Copyright (c) 2014 Thomas H. Jonell
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program. If not, see .
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BehaviorLibrary.Components.Utility
+{
+ public class UtilityVector
+ {
+ public UtilityVector(params float[] values){
+ this.values = values;
+ }
+
+ public float[] values{ get; set; }
+
+ //return the magnitude of this vector
+ public float magnitude{
+ get{
+ float mag = 0;
+ for (int i = 0; i < this.values.Length; i++)
+ mag += this.values [i] * this.values [i];
+
+ return (float) Math.Sqrt (mag);
+ }
+ }
+
+ ///
+ /// Return a new vector based on the normalization of this instance.
+ ///
+ public UtilityVector normalize(){
+ if (this.values.Length <= 0)
+ return null;
+
+ UtilityVector vec = new UtilityVector();
+ vec.values = new float[this.values.Length];
+ this.values.CopyTo (vec.values, 0);
+
+ float mag = vec.magnitude;
+
+ for (int i = 0; i < vec.values.Length; i++)
+ vec.values [i] = vec.values [i] / mag;
+
+ return vec;
+ }
+
+ ///
+ /// Dot between this and another specified vector. (based on normalized vectors)
+ ///
+ /// Vector.
+ public float dot(UtilityVector vector){
+ if (this.magnitude == 0 || vector.magnitude == 0)
+ return -2;
+
+ UtilityVector a = this.normalize ();
+ UtilityVector b = vector.normalize ();
+
+ float val = 0;
+
+ for (int i = 0; i < this.values.Length; i++)
+ val += a.values [i] * b.values [i];
+
+ return val;
+ }
+ }
+}
\ No newline at end of file
diff --git a/BehaviorLibrary/TreeContext.cs b/BehaviorLibrary/TreeContext.cs
new file mode 100644
index 0000000..5274ca0
--- /dev/null
+++ b/BehaviorLibrary/TreeContext.cs
@@ -0,0 +1,96 @@
+using BehaviorLibrary.Components;
+using BehaviorLibrary.Components.Actions;
+using System.Collections.Generic;
+
+namespace BehaviorLibrary
+{
+ public class TreeContext
+ {
+ private List calling;
+ private List called;
+ private int callCount;
+ private List onNotCalledBehaviors;
+ private bool isInvokingFinalizer;
+
+ public TreeContext()
+ {
+ this.calling = new List();
+ this.called = new List();
+ this.onNotCalledBehaviors = new List();
+ }
+
+ public BehaviorComponent[] Calling { get { return this.calling.ToArray(); } }
+ public BehaviorComponent[] Called { get { return this.called.ToArray(); } }
+
+ public TreeContext(TreeContext oldContext) : this()
+ {
+ this.OldContext = oldContext;
+ }
+
+ public CallHierarchy CallingHierarchy
+ {
+ get
+ {
+ return new CallHierarchy(this.calling);
+ }
+ }
+
+ public TreeContext OldContext { get; private set; }
+
+ private void AddToCalling(BehaviorComponent behavior)
+ {
+ this.calling.Add(behavior);
+ }
+
+ private void AddToCalled(BehaviorComponent behavior)
+ {
+ this.called.Add(behavior);
+ }
+
+ public bool HasBeenCalled(BehaviorComponent behavior)
+ {
+ return this.called.Contains(behavior);
+ }
+
+ public bool IsCalling(BehaviorComponent behavior)
+ {
+ return this.calling.Contains(behavior);
+ }
+
+ public void OnAboutToCall(BehaviorComponent caller)
+ {
+ this.AddToCalling(caller);
+ this.callCount++;
+ }
+
+ public void RegisterOnNotCalledBehavior(OnNotCalled onNotCalledBehavior)
+ {
+ this.onNotCalledBehaviors.Add(onNotCalledBehavior);
+ }
+
+ public void OnCalled(BehaviorComponent called, BehaviorReturnCode result)
+ {
+ this.AddToCalled(called);
+
+ // Check if we just called the root node, so are done with the tree.
+ if (!this.isInvokingFinalizer && this.calling.Count > 0 && this.calling[0] == called)
+ {
+ this.ProcessFinalizers(this.calling[0]);
+ }
+ }
+
+ private void ProcessFinalizers(BehaviorComponent rootNode)
+ {
+ if (this.OldContext == null) return;
+ foreach (var onNotCalledBehavior in this.OldContext.onNotCalledBehaviors)
+ {
+ if (!this.HasBeenCalled(onNotCalledBehavior))
+ {
+ this.isInvokingFinalizer = true;
+ onNotCalledBehavior.InvokeFinalizer(this);
+ this.isInvokingFinalizer = false;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index bafd1b8..8963121 100644
--- a/README.md
+++ b/README.md
@@ -3,17 +3,38 @@ Behavior Library
BehaviorLibrary is a framework for creating behavior trees for game AI. It is free to use, modify, and redestribute as covered under the attached License (FreeBSD).
+Changes
+-------
+
+RootSelector has been refactored to IndexSelector. It works exactly the same, just has a more appropriate name.
+
+Behavior has had an additional constructor added that allows BehaviorComponent objects to be used rather than just RootSelector/IndexSelector objects.
+
+Merged in new Repeater, Succeeder, RepeatUntilFail Decorators.
+
+
+Utilities
+---------
+
+Added Utility components, see Utility Test cases for test examples.
+
+The basic point is to use a vector of floating numbers representing weights/values that will be paired with a BehaviorComponent object. When a UtilitySelector is called, it will execute a function that returns a UtilityVector that will then be compared against the BehaviorComponents' paired vectors (via a dot product) and select the pair that best matches and execute its Behavior.
+
+
+Example
+-------
+
It is simple to use and with that simplicity comes performance.
Example of a simple A* following AI on a tilemap
//setup all coniditionals and their delegate functions
- Coniditional tooClose = new Conditional(isTooClose);
- Coniditional targetMoved = new Conditional(hasTargetMoved);
- Coniditional pathFound = new Conditional(hasPathBeenFound);
- Coniditional reachedCell = new Conditional(hasReachedCell);
- Coniditional reachedTarget = new Conditional(hasReachedTarget);
- Coniditional isNewPath = new Conditional(hasNewPath);
+ Conditional tooClose = new Conditional(isTooClose);
+ Conditional targetMoved = new Conditional(hasTargetMoved);
+ Conditional pathFound = new Conditional(hasPathBeenFound);
+ Conditional reachedCell = new Conditional(hasReachedCell);
+ Conditional reachedTarget = new Conditional(hasReachedTarget);
+ Conditional isNewPath = new Conditional(hasNewPath);
//setup all actions and their delegate functions
BehaviorAction moveToCell = new BehaviorAction(moveTowardsCell);
@@ -27,20 +48,20 @@ Example of a simple A* following AI on a tilemap
BehaviorAction animate = new BehaviorAction(updateAnimation);
//setup an initilization branch
- ParallelSequence initialize = new ParallelSequence(initPathfinder, calcPath);
+ Sequence initialize = new Sequence(initPathfinder, calcPath);
//if the target has moved, reset and calculate a new path
- ParallelSelector ifMovedCreateNewPath = new ParallelSelector(new Inverter(targetMoved), new Inverter(reset), calcPath);
- ParallelSelector ifPathFoundGetPath = new ParallelSelector(new Inverter(pathFound), getPath);
- ParallelSelector ifPathNewUseIt = new ParallelSelector(new Inverter(isNewPath), setPath);
- ParallelSelector ifReachedCellGetNext = new ParallelSelector(new Inverter(reachedCell), getNextCell);
- ParallelSelector ifNotReachedTargetMoveTowardsCell = new ParallelSelector(reachedTarget, moveToCell);
+ Selector ifMovedCreateNewPath = new Selector(new Inverter(targetMoved), new Inverter(reset), calcPath);
+ Selector ifPathFoundGetPath = new Selector(new Inverter(pathFound), getPath);
+ Selector ifPathNewUseIt = new Selector(new Inverter(isNewPath), setPath);
+ Selector ifReachedCellGetNext = new Selector(new Inverter(reachedCell), getNextCell);
+ Selector ifNotReachedTargetMoveTowardsCell = new Selector(reachedTarget, moveToCell);
//follow target so long as you're not too close and then animate
- ParallelSequence follow = new ParallelSequence(new Inverter(tooClose), updatePosition, ifMovedCreateNewPath, ifPathFoundGetPath, ifPathIsNewUseIt, ifReachedCellGetNext, ifNotReachedTargetMoveTowardsCell, animate);
+ Sequence follow = new Sequence(new Inverter(tooClose), updatePosition, ifMovedCreateNewPath, ifPathFoundGetPath, ifPathIsNewUseIt, ifReachedCellGetNext, ifNotReachedTargetMoveTowardsCell, animate);
//setup root node, choose initialization phase or pathing/movement phase
- RootSelector root = new RootSelector(switchBehaviors, initialize, follow);
+ IndexSelector root = new IndexSelector(switchBehaviors, initialize, follow);
//set a reference to the root
Behavior behavior = new Behavior(root);
diff --git a/Tests/Issue2.cs b/Tests/Issue2.cs
new file mode 100644
index 0000000..b1889cf
--- /dev/null
+++ b/Tests/Issue2.cs
@@ -0,0 +1,85 @@
+using System;
+using CSTester;
+using CSLogging;
+using BehaviorLibrary;
+using BehaviorLibrary.Components;
+using BehaviorLibrary.Components.Composites;
+using BehaviorLibrary.Components.Actions;
+
+namespace Tests
+{
+ [TestCase]
+ public class Issue2
+ {
+ public Issue2 ()
+ {
+ }
+
+ CSLogger _log = CSLogger.Instance;
+
+ [BuildUp]
+ public void buildup(){
+ _log.setEnableLogging (true);
+ _log.setEnableDebug (true);
+ _log.setEnableError (true);
+ _log.setEnableMessage (true);
+ _log.loadLog ("./", "issue2.log");
+ _log.enterScope ("buildup");
+ _log.logMessage ("---------- BEGIN TESTING ISSUE 2 ----------");
+ _log.exitScope ();
+ }
+
+ [TearDown]
+ public void teardown(){
+ _log.enterScope ("teardown");
+ _log.logMessage ("---------- END TESTING ISSUE 2 ----------");
+ _log.exitScope ();
+ _log.closeLog ();
+ }
+
+ [Test]
+ public void test1(){
+ _log.enterScope ("test1");
+
+ var foo = new Sequence (new BehaviorAction (delegate() {
+ return BehaviorReturnCode.Running;
+ }), new BehaviorAction (delegate() {
+ return BehaviorReturnCode.Running;
+ }), new BehaviorAction (delegate() {
+ return BehaviorReturnCode.Running;
+ }), new BehaviorAction (delegate() {
+ return BehaviorReturnCode.Running;
+ }));
+
+ Verify.VerifyEquals ("all running is running", true, foo.Behave(), BehaviorReturnCode.Running);
+
+ foo = new Sequence (new BehaviorAction (delegate() {
+ return BehaviorReturnCode.Running;
+ }), new BehaviorAction (delegate() {
+ return BehaviorReturnCode.Running;
+ }), new BehaviorAction (delegate() {
+ return BehaviorReturnCode.Running;
+ }), new BehaviorAction (delegate() {
+ return BehaviorReturnCode.Success;
+ }));
+
+ Verify.VerifyEquals ("all but one running is running", true, foo.Behave(), BehaviorReturnCode.Running);
+
+ foo = new Sequence (new BehaviorAction (delegate() {
+ return BehaviorReturnCode.Success;
+ }), new BehaviorAction (delegate() {
+ return BehaviorReturnCode.Success;
+ }), new BehaviorAction (delegate() {
+ return BehaviorReturnCode.Success;
+ }), new BehaviorAction (delegate() {
+ return BehaviorReturnCode.Success;
+ }));
+
+ Verify.VerifyEquals ("all success is success", true, foo.Behave(), BehaviorReturnCode.Success);
+
+
+ _log.exitScope ();
+ }
+ }
+}
+
diff --git a/Tests/Issue7.cs b/Tests/Issue7.cs
new file mode 100644
index 0000000..f7f7f04
--- /dev/null
+++ b/Tests/Issue7.cs
@@ -0,0 +1,85 @@
+using System;
+using CSTester;
+using CSLogging;
+using BehaviorLibrary;
+using BehaviorLibrary.Components.Composites;
+using BehaviorLibrary.Components.Actions;
+
+namespace Tests
+{
+ [TestCase]
+ public class Issue7
+ {
+ public Issue7 ()
+ {
+ }
+
+ private CSLogger _log = CSLogger.Instance;
+
+ [BuildUp]
+ public void build_up(){
+ _log.setEnableLogging (true);
+ _log.setEnableDebug (true);
+ _log.setEnableError (true);
+ _log.setEnableMessage (true);
+ _log.loadLog ("./", "issue7.log");
+ _log.enterScope ();
+ _log.logMessage ("---------- BEGIN TESTING ISSUE 7 ----------");
+ _log.exitScope ();
+
+ }
+
+ [TearDown]
+ public void tear_down(){
+ _log.enterScope ();
+ _log.logMessage ("---------- END TESTING ISSUE 7 ----------");
+ _log.exitScope ();
+ _log.closeLog ();
+ }
+
+ private int[] counts = new int[4];
+
+ public BehaviorReturnCode component_1(){
+ counts [0]++;
+
+ return BehaviorReturnCode.Success;
+ }
+
+ public BehaviorReturnCode component_2(){
+ counts [1]++;
+ return BehaviorReturnCode.Success;
+ }
+
+ public BehaviorReturnCode component_3(){
+ counts [2]++;
+ return BehaviorReturnCode.Success;
+ }
+
+ public BehaviorReturnCode component_4(){
+ counts [3]++;
+ return BehaviorReturnCode.Success;
+ }
+
+
+ [Test]
+ public void test_1(){
+ _log.enterScope ();
+
+ RandomSelector rs = new RandomSelector (new BehaviorAction(component_1),
+ new BehaviorAction(component_2),
+ new BehaviorAction(component_3),
+ new BehaviorAction(component_4));
+
+
+ for (int i = 0; i < 100000; i++)
+ rs.Behave ();
+
+ _log.logMessage ("1:" + counts[0] +", 2:" + counts[1]+ ", 3:" + counts[2]+ ", 4:" + counts [3]);
+
+ Verify.VerifyTrue ("verify last component actioned", true, counts [3] > 0);
+
+ _log.exitScope ();
+ }
+ }
+}
+
diff --git a/Tests/Program.cs b/Tests/Program.cs
new file mode 100644
index 0000000..cb82c06
--- /dev/null
+++ b/Tests/Program.cs
@@ -0,0 +1,45 @@
+//
+// Program.cs
+//
+// Author:
+// Thomas H. Jonell <@Net_Gnome>
+//
+// Copyright (c) 2013 Thomas H. Jonell
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program. If not, see .
+using System;
+using CSTester;
+using CSLogging;
+
+namespace Tests
+{
+ class MainClass
+ {
+ public static void Main (string[] args)
+ {
+ try
+ {
+ Tester tester = new Tester();
+ tester.registerTestCases();
+ tester.executeTestCases();
+ Console.Write(tester.getResults());
+ }
+ catch (Exception e)
+ {
+ Console.Write(e.ToString());
+ }
+ }
+
+ }
+}
diff --git a/Tests/Properties/AssemblyInfo.cs b/Tests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..d1009d6
--- /dev/null
+++ b/Tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,22 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+[assembly: AssemblyTitle ("Tests")]
+[assembly: AssemblyDescription ("")]
+[assembly: AssemblyConfiguration ("")]
+[assembly: AssemblyCompany ("")]
+[assembly: AssemblyProduct ("")]
+[assembly: AssemblyCopyright ("tom")]
+[assembly: AssemblyTrademark ("")]
+[assembly: AssemblyCulture ("")]
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+[assembly: AssemblyVersion ("1.0.*")]
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+
diff --git a/Tests/TestCases.cs b/Tests/TestCases.cs
new file mode 100644
index 0000000..0eb4a51
--- /dev/null
+++ b/Tests/TestCases.cs
@@ -0,0 +1,138 @@
+//
+// TestCases.cs
+//
+// Author:
+// Thomas H. Jonell <@Net_Gnome>
+//
+// Copyright (c) 2013 Thomas H. Jonell
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program. If not, see .
+using System;
+using CSTester;
+using CSLogging;
+using BehaviorLibrary;
+using BehaviorLibrary.Components;
+using BehaviorLibrary.Components.Actions;
+
+namespace Tests
+{
+ [TestCase]
+ public class TestCases
+ {
+ public TestCases (){}
+
+ private CSLogger _log = CSLogger.Instance;
+
+ [BuildUp]
+ public void buildup(){
+ _log.setEnableLogging (true);
+ _log.setEnableDebug (true);
+ _log.setEnableError (true);
+ _log.setEnableMessage (true);
+ _log.loadLog("","behaviorLibrary.log");
+ _log.enterScope ("TestCases");
+ _log.logMessage ("----------------- STARTING BEHAVIOR LIBRARY TESTS -----------------");
+ }
+
+ [TearDown]
+ public void teardown(){
+ _log.enterScope("teardown");
+ _log.exitScope ();
+ _log.logMessage ("----------------- ENDING BEHAVIOR LIBRARY TESTS -----------------");
+ _log.exitScope ();
+ _log.closeLog ();
+ }
+
+ [Test]
+ public void testStatefulSeq(){
+ _log.enterScope("testStatefulSeq");
+
+ bool first = true;
+
+ var foo = new StatefulSequence (new BehaviorAction(delegate(){
+ if(first){
+ return BehaviorReturnCode.Success;
+ }else{
+ return BehaviorReturnCode.Failure;
+ }
+ }),new BehaviorAction( delegate(){
+ if(first){
+ first = false;
+ return BehaviorReturnCode.Running;
+ }else{
+ return BehaviorReturnCode.Success;
+ }
+ }),new BehaviorAction(delegate(){
+ return BehaviorReturnCode.Success;
+ }));
+
+ Verify.VerifyEquals ("1st running", true, foo.Behave (), BehaviorReturnCode.Running);
+ Verify.VerifyEquals ("2nd success", true, foo.Behave (), BehaviorReturnCode.Success);
+ Verify.VerifyEquals ("3rd failure", true, foo.Behave (), BehaviorReturnCode.Failure);
+
+ _log.logMessage ("restting first");
+ first = true;
+
+ Verify.VerifyEquals ("after reset running", true, foo.Behave (), BehaviorReturnCode.Running);
+ Verify.VerifyEquals ("final success", true, foo.Behave (), BehaviorReturnCode.Success);
+ Verify.VerifyEquals ("final failure", true, foo.Behave (), BehaviorReturnCode.Failure);
+
+ _log.exitScope ();
+ }
+
+ [Test]
+ public void testStatefulSel(){
+ _log.enterScope("testStatefulSel");
+
+ bool first = true;
+ bool second = true;
+ var foo = new StatefulSelector (new BehaviorAction (delegate(){
+ return BehaviorReturnCode.Failure;
+ }), new BehaviorAction (delegate() {
+ if(first){
+ first = false;
+ return BehaviorReturnCode.Running;
+ }else{
+ return BehaviorReturnCode.Failure;
+ }
+ }), new BehaviorAction (delegate(){
+ if(first){
+ return BehaviorReturnCode.Success;
+ }else{
+ if(second){
+ second = false;
+ return BehaviorReturnCode.Success;
+ }else{
+ return BehaviorReturnCode.Failure;
+ }
+ }
+ }));
+
+ Verify.VerifyEquals ("1st running", true, foo.Behave (), BehaviorReturnCode.Running);
+ Verify.VerifyEquals ("2nd success", true, foo.Behave (), BehaviorReturnCode.Success);
+ Verify.VerifyEquals ("3rd failure", true, foo.Behave (), BehaviorReturnCode.Failure);
+
+ _log.logMessage ("restting flags");
+ first = true;
+ second = true;
+
+ Verify.VerifyEquals ("after reset running", true, foo.Behave (), BehaviorReturnCode.Running);
+ Verify.VerifyEquals ("final success", true, foo.Behave (), BehaviorReturnCode.Success);
+ Verify.VerifyEquals ("final failure", true, foo.Behave (), BehaviorReturnCode.Failure);
+
+ _log.exitScope ();
+ }
+ }
+}
+
diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj
new file mode 100644
index 0000000..b8da6f3
--- /dev/null
+++ b/Tests/Tests.csproj
@@ -0,0 +1,55 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {A7D9F051-A51E-42FF-AD2B-D94DC8A06650}
+ Exe
+ Tests
+ Tests
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;TRACE
+ prompt
+ 4
+ true
+
+
+ full
+ true
+ bin\Release
+ prompt
+ 4
+ true
+
+
+
+
+ ..\..\CSTester\CSLogging\bin\Release\CSLogging.dll
+
+
+ ..\..\CSTester\CSTester\bin\Release\CSTester.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {CC824B6F-6145-485F-9604-FB94F0ECACA7}
+ BehaviorLibrary
+
+
+
\ No newline at end of file
diff --git a/Tests/UtilityTests.cs b/Tests/UtilityTests.cs
new file mode 100644
index 0000000..f71587c
--- /dev/null
+++ b/Tests/UtilityTests.cs
@@ -0,0 +1,257 @@
+//
+// UtilityTests.cs
+//
+// Author:
+// Thomas H. Jonell <@Net_Gnome>
+//
+// Copyright (c) 2014 Thomas H. Jonell
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program. If not, see .
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+
+
+using CSTester;
+using CSLogging;
+
+using BehaviorLibrary;
+using BehaviorLibrary.Components;
+using BehaviorLibrary.Components.Utility;
+using BehaviorLibrary.Components.Actions;
+
+namespace Tests
+{
+ [TestCase]
+ class UtilityTests
+ {
+
+ private CSLogger _log = CSLogger.Instance;
+
+ [BuildUp]
+ public void buildup()
+ {
+ _log.setEnableLogging(true);
+ _log.setEnableDebug(true);
+ _log.setEnableError(true);
+ _log.setEnableMessage(true);
+ _log.loadLog("", "utility_tests.log");
+ _log.enterScope();
+ _log.logMessage("----------------- STARTING BEHAVIOR LIBRARY UTILITY TESTS -----------------");
+ }
+
+ [TearDown]
+ public void teardown()
+ {
+ _log.enterScope();
+ _log.exitScope();
+ _log.logMessage("----------------- ENDING BEHAVIOR LIBRARY UTILITY TESTS -----------------");
+ _log.exitScope();
+ _log.closeLog();
+ }
+
+ [Test]
+ public void test_vector(){
+ _log.enterScope ();
+
+ UtilityVector vec1 = new UtilityVector (0, 1, 2, 3, 4, 5);
+
+ float mag = vec1.magnitude;
+ _log.logDebug ("mag: " + mag);
+ Verify.VerifyTrue ("verify mag gte 0", true, mag >= 0);
+
+ Verify.VerifyTrue ("norm is not null", true, vec1.normalize () != null);
+
+ UtilityVector vec2 = new UtilityVector (5, 4, 3, 2, 1, 0);
+
+ float dot = vec1.dot (vec2);
+ _log.logDebug ("dot: " + dot);
+ Verify.VerifyTrue ("dot between 1 and -1", true, (dot <= 1) && (dot >= -1));
+
+ dot = vec1.dot (vec1);
+ _log.logDebug ("self dot: " + dot);
+ Verify.VerifyTrue ("dot with itself should be 1", true, dot == 1);
+
+
+ _log.exitScope ();
+ }
+
+ [Test]
+ public void selector_1()
+ {
+ _log.enterScope();
+
+ UtilityVector vector = new UtilityVector(0, 1, 0, 2);
+ BehaviorAction action = new BehaviorAction(delegate() { return BehaviorReturnCode.Success; });
+ UtilityPair pair = new UtilityPair(vector, action);
+ UtilitySelector sel = new UtilitySelector(delegate(){return new UtilityVector(0,1,1,2);},pair,pair);
+
+ BehaviorReturnCode result = sel.Behave();
+
+ Verify.VerifyNotEquals("basic vector compare", true, result, BehaviorReturnCode.Failure);
+
+ _log.exitScope();
+ }
+
+ [Test]
+ public void selector_2(){
+ _log.enterScope();
+
+ //build vectors
+ UtilityVector a = new UtilityVector(0, 1, 0, 1);
+ UtilityVector b = new UtilityVector(1, 1, 0, 0);
+ UtilityVector c = new UtilityVector(1, 0, 1, 0);
+ UtilityVector d = new UtilityVector(0, 0, 1, 1);
+
+ string choice = "";
+
+ //build actions that change choice if called
+ BehaviorAction aa = new BehaviorAction (delegate() {
+ choice = "a";
+ return BehaviorReturnCode.Success;
+ });
+ BehaviorAction ba = new BehaviorAction (delegate() {
+ choice = "b";
+ return BehaviorReturnCode.Success;
+ });
+ BehaviorAction ca = new BehaviorAction (delegate() {
+ choice = "c";
+ return BehaviorReturnCode.Success;
+ });
+ BehaviorAction da = new BehaviorAction (delegate() {
+ choice = "d";
+ return BehaviorReturnCode.Success;
+ });
+
+ //build the appropraite pairs
+ UtilityPair ap = new UtilityPair (a, aa);
+ UtilityPair bp = new UtilityPair (b, ba);
+ UtilityPair cp = new UtilityPair (c, ca);
+ UtilityPair dp = new UtilityPair (d, da);
+
+
+ //execute tests
+ UtilitySelector sel = new UtilitySelector (delegate() {
+ return new UtilityVector (0,1,0,1);
+ }, ap, bp, cp, dp);
+
+ sel.Behave ();
+
+ Verify.VerifyTrue ("a chosen", true, choice == "a");
+
+ sel = new UtilitySelector (delegate() {
+ return new UtilityVector (1,1,0,0);
+ }, ap, bp, cp, dp);
+
+ sel.Behave ();
+
+ Verify.VerifyTrue ("b chosen", true, choice == "b");
+
+ sel = new UtilitySelector (delegate() {
+ return new UtilityVector (1,0,1,0);
+ }, ap, bp, cp, dp);
+
+ sel.Behave ();
+
+ Verify.VerifyTrue ("c chosen", true, choice == "c");
+
+ sel = new UtilitySelector (delegate() {
+ return new UtilityVector (0,0,1,1);
+ }, ap, bp, cp, dp);
+
+ sel.Behave ();
+
+ Verify.VerifyTrue ("d chosen", true, choice == "d");
+
+
+ _log.exitScope ();
+ }
+
+ [Test]
+ public void selector_3(){
+ _log.enterScope();
+
+ //build vectors
+ UtilityVector a = new UtilityVector(0, 1, 0, 1);
+ UtilityVector b = new UtilityVector(1, 1, 0, 0);
+ UtilityVector c = new UtilityVector(1, 0, 1, 0);
+ UtilityVector d = new UtilityVector(0, 0, 1, 1);
+
+ string choice = "";
+
+ //build actions that change choice if called
+ BehaviorAction aa = new BehaviorAction (delegate() {
+ choice = "a";
+ return BehaviorReturnCode.Success;
+ });
+ BehaviorAction ba = new BehaviorAction (delegate() {
+ choice = "b";
+ return BehaviorReturnCode.Success;
+ });
+ BehaviorAction ca = new BehaviorAction (delegate() {
+ choice = "c";
+ return BehaviorReturnCode.Success;
+ });
+ BehaviorAction da = new BehaviorAction (delegate() {
+ choice = "d";
+ return BehaviorReturnCode.Success;
+ });
+
+ //build the appropraite pairs
+ UtilityPair ap = new UtilityPair (a, aa);
+ UtilityPair bp = new UtilityPair (b, ba);
+ UtilityPair cp = new UtilityPair (c, ca);
+ UtilityPair dp = new UtilityPair (d, da);
+
+
+ //execute tests
+ UtilitySelector sel = new UtilitySelector (delegate() {
+ return new UtilityVector (0.5f,0.7f,0.4f,0.8f);
+ }, ap, bp, cp, dp);
+
+ sel.Behave ();
+
+ Verify.VerifyTrue ("a chosen", true, choice == "a");
+
+ sel = new UtilitySelector (delegate() {
+ return new UtilityVector (0.7f,0.8f,0.5f,0.4f);
+ }, ap, bp, cp, dp);
+
+ sel.Behave ();
+
+ Verify.VerifyTrue ("b chosen", true, choice == "b");
+
+ sel = new UtilitySelector (delegate() {
+ return new UtilityVector (0.7f,0.5f,0.8f,0.4f);
+ }, ap, bp, cp, dp);
+
+ sel.Behave ();
+
+ Verify.VerifyTrue ("c chosen", true, choice == "c");
+
+ sel = new UtilitySelector (delegate() {
+ return new UtilityVector (0.5f,0.4f,0.7f,0.8f);
+ }, ap, bp, cp, dp);
+
+ sel.Behave ();
+
+ Verify.VerifyTrue ("d chosen", true, choice == "d");
+
+
+ _log.exitScope ();
+ }
+ }
+}