Skip to content

Commit

Permalink
1.2.5: Refactored StateMachine.UpdateState to now be compatible with …
Browse files Browse the repository at this point in the history
…the UI via direct invocation. Fixed missing references in manual for improving the docs. Various improvements to documentation.
  • Loading branch information
pablothedolphin committed Aug 23, 2019
1 parent afd43f2 commit 9f54f10
Show file tree
Hide file tree
Showing 170 changed files with 9,409 additions and 638 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,20 @@ public override bool RaiseEvent ([CallerFilePath] string fileName = "", [CallerM
{
#if UNITY_EDITOR
if (ScriptableFrameworkSettings.EditorEventLogging)
{
#endif
Debug.Log (string.Format ("[EVENT] '{0}' was raised from {1}.{2}() at line {3}", name, Path.GetFileNameWithoutExtension (fileName), methodName, callerLineNumber));
//System.Diagnostics.StackFrame stackFrame = new System.Diagnostics.StackFrame (1, false);


//Debug.Log (string.Format ("[EVENT] '{0}' was raised from {1}.{2} at line {3}", name, Path.GetFileNameWithoutExtension (stackFrame.GetFileName ()), stackFrame.GetMethod ().Name, stackFrame.GetFileLineNumber ()));
Debug.Log (string.Format ("[EVENT] '{0}' was raised from {1}.{2}() at line {3}", name, Path.GetFileNameWithoutExtension (fileName), methodName, callerLineNumber));

if (listeners.Count == 0)
#if UNITY_EDITOR
}
#endif


if (listeners.Count == 0)
{
Debug.LogWarning (string.Format ("[EVENT] '{0}' was raised but has no listeners", name));
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ public abstract class RuntimeList<T> : RuntimeObject, IList<T>
/// <summary>
/// A list of the elements in this object to be accessed externally via square bracket operator.
/// </summary>
/// <value>The internal list that actually contains the elements of this object.</value>
[Space]
[SerializeField]
protected List<T> items = new List<T> ();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,58 +22,49 @@ public class StateMachine : StateMachineBase
/// Actually runs the loop which sets the GameObjects on or off.
/// </summary>
/// <param name="newSelectionIndex">Index of the object to be left on.</param>
/// <returns>Whether or not the operation succeeded.</returns>
protected override bool ApplyState(int newSelectionIndex)
protected override void ApplyState(int newSelectionIndex)
{
selectionIndex = newSelectionIndex;

for (int i = 0; i < gameObjects.Count; i++)
{
if (!CheckListItemBeforeUpdate(i)) return false;
if (!CheckListItemBeforeUpdate(i)) return;

gameObjects[i].SetActive(i == selectionIndex);
}

return true;
}

/// <summary>
/// Actually runs the loop which sets all the GameObjects on or off.
/// </summary>
/// <param name="stateForAll">The new state for all GameObjects.</param>
/// <returns>Whether or not the operation succeeded.</returns>
protected override bool ApplyState(bool stateForAll)
protected override void ApplyState (bool stateForAll)
{
selectionIndex = -1;

for (int i = 0; i < gameObjects.Count; i++)
{
if (!CheckListItemBeforeUpdate(i)) return false;
if (!CheckListItemBeforeUpdate(i)) return;

gameObjects[i].SetActive(stateForAll);
}

return true;
}

/// <summary>
/// Actually applies the new state to the selected object.
/// </summary>
/// <param name="newSelectionIndex">The index of the object to update.</param>
/// <param name="stateAtThisObject">The state to provide that object with.</param>
/// <returns>Whether or not the operation succeeded.</returns>
protected override bool ApplyState(int newSelectionIndex, bool stateAtThisObject)
protected override void ApplyState (int newSelectionIndex, bool stateAtThisObject)
{
selectionIndex = -1;

for (int i = 0; i < gameObjects.Count; i++)
{
if (!CheckListItemBeforeUpdate(i)) return false;
if (!CheckListItemBeforeUpdate(i)) return;
}

gameObjects[newSelectionIndex].SetActive(stateAtThisObject);

return true;
}

/// <summary>
Expand All @@ -82,22 +73,19 @@ protected override bool ApplyState(int newSelectionIndex, bool stateAtThisObject
/// <param name="startIndex">Where to start applying your state (inclusive).</param>
/// <param name="length">How many objects to affect.</param>
/// <param name="stateToApply">The state to apply within your given range.</param>
/// <returns>Whether or not the operation succeeded.</returns>
protected override bool ApplyState(int startIndex, int length, bool stateToApply)
protected override void ApplyState (int startIndex, int length, bool stateToApply)
{
selectionIndex = -1;

for (int i = 0; i < gameObjects.Count; i++)
{
if (!CheckListItemBeforeUpdate(i)) return false;
if (!CheckListItemBeforeUpdate(i)) return;

if (i >= startIndex && i < startIndex + length)
gameObjects[i].SetActive (stateToApply);
else
gameObjects[i].SetActive (!stateToApply);
}

return true;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,41 +28,38 @@ public abstract class StateMachineBase : RuntimeObject
/// </summary>
/// <param name="newSelectionIndex">Index of the state to be active.</param>
/// <param name="onlyThisObject">If true, the update for all other objects will be skipped.</param>
/// <returns>Whether or not the operation succeeded.</returns>
public bool UpdateState (int newSelectionIndex)
public void UpdateState (int newSelectionIndex)
{
if (!CheckListBeforeUpdate ()) return false;
if (!CheckListBeforeUpdate ()) return;

if (!CheckSelectionIndexBeforeUpdate (newSelectionIndex)) return false;
if (!CheckSelectionIndexBeforeUpdate (newSelectionIndex)) return;

return ApplyState (newSelectionIndex);
ApplyState (newSelectionIndex);
}

/// <summary>
/// Applies the same state to all objects in the current list.
/// </summary>
/// <param name="stateForAll">The new state for all contained object.</param>
/// <returns>Whether or not the operation succeeded.</returns>
public bool UpdateState (bool stateForAll)
public void UpdateState (bool stateForAll)
{
if (!CheckListBeforeUpdate ()) return false;
if (!CheckListBeforeUpdate ()) return;

return ApplyState (stateForAll);
ApplyState (stateForAll);
}

/// <summary>
/// Applies a state to a single object without affecting other objects in the list.
/// </summary>
/// <param name="newSelectionIndex">The index of the object to update.</param>
/// <param name="stateAtThisObject">The state to provide that object with.</param>
/// <returns>Whether or not the operation succeeded.</returns>
public bool UpdateState (int newSelectionIndex, bool stateAtThisObject)
public void UpdateState (int newSelectionIndex, bool stateAtThisObject)
{
if (!CheckListBeforeUpdate ()) return false;
if (!CheckListBeforeUpdate ()) return;

if (!CheckSelectionIndexBeforeUpdate (newSelectionIndex)) return false;
if (!CheckSelectionIndexBeforeUpdate (newSelectionIndex)) return;

return ApplyState (newSelectionIndex, stateAtThisObject);
ApplyState (newSelectionIndex, stateAtThisObject);
}

/// <summary>
Expand All @@ -72,45 +69,40 @@ public bool UpdateState (int newSelectionIndex, bool stateAtThisObject)
/// <param name="startIndex">Where to start applying your state (inclusive).</param>
/// <param name="length">How many objects to affect.</param>
/// <param name="stateToApply">The state to apply within your given range.</param>
/// <returns>Whether or not the operation succeeded.</returns>
public bool UpdateState (int startIndex, int length, bool stateToApply)
public void UpdateState (int startIndex, int length, bool stateToApply)
{
if (!CheckListBeforeUpdate ()) return false;
if (!CheckListBeforeUpdate ()) return;

return ApplyState (startIndex, length, stateToApply);
ApplyState (startIndex, length, stateToApply);
}

/// <summary>
/// Actually runs the loop which updates the state.
/// </summary>
/// <param name="newSelectionIndex">Index of the state to be active.</param>
/// <param name="onlyThisObject">If true, the update for all other objects will be skipped.</param>
/// <returns>Whether or not the operation succeeded.</returns>
protected abstract bool ApplyState (int newSelectionIndex);
protected abstract void ApplyState (int newSelectionIndex);

/// <summary>
/// Actually runs the loop which sets the state of all objects in the list.
/// </summary>
/// <param name="stateForAll">State to apply for all.</param>
/// <returns>Whether or not the operation succeeded.</returns>
protected abstract bool ApplyState (bool stateForAll);
protected abstract void ApplyState (bool stateForAll);

/// <summary>
/// Actually applies the new state to the selected object.
/// </summary>
/// <param name="newSelectionIndex">The index of the object to update.</param>
/// <param name="stateAtThisObject">The state to provide that object with.</param>
/// <returns>Whether or not the operation succeeded.</returns>
protected abstract bool ApplyState (int newSelectionIndex, bool stateAtThisObject);
protected abstract void ApplyState (int newSelectionIndex, bool stateAtThisObject);

/// <summary>
/// Actually runs the loop which applies your given range of objects and the rest with another.
/// </summary>
/// <param name="startIndex">Where to start applying your state (inclusive).</param>
/// <param name="length">How many objects to affect.</param>
/// <param name="stateToApply">The state to apply within your given range.</param>
/// <returns>Whether or not the operation succeeded.</returns>
protected abstract bool ApplyState (int startIndex, int length, bool stateToApply);
protected abstract void ApplyState (int startIndex, int length, bool stateToApply);

/// <summary>
/// Checks if the list is null. Since the list can be a varying type, defining this as
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,55 +22,46 @@ public class StateMachineController : StateMachineBase
/// Actually runs the loop which sets each object's state on or off.
/// </summary>
/// <param name="newSelectionIndex">Index of the state to be active.</param>
/// <returns>Whether or not the operation succeeded.</returns>
protected override bool ApplyState (int newSelectionIndex)
protected override void ApplyState (int newSelectionIndex)
{
selectionIndex = newSelectionIndex;

for (int i = 0; i < subStateMachines.Count; i++)
{
if (!CheckListItemBeforeUpdate (i)) return false;
if (!CheckListItemBeforeUpdate (i)) return;

subStateMachines[i].UpdateState (i == selectionIndex);
}

return true;
}

/// <summary>
/// Actually runs the loop which sets each object's state on or off.
/// </summary>
/// <param name="stateForAll">The new state for all objects.</param>
/// <returns>Whether or not the operation succeeded.</returns>
protected override bool ApplyState (bool stateForAll)
protected override void ApplyState (bool stateForAll)
{
selectionIndex = -1;

for (int i = 0; i < subStateMachines.Count; i++)
{
if (!CheckListItemBeforeUpdate (i)) return false;
if (!CheckListItemBeforeUpdate (i)) return;

subStateMachines[i].UpdateState (stateForAll);
}

return true;
}

/// <summary>
/// Actually applies the new state to the selected object.
/// </summary>
/// <param name="newSelectionIndex">The index of the object to update.</param>
/// <param name="stateAtThisObject">The state to provide that object with.</param>
/// <returns>Whether or not the operation succeeded.</returns>
protected override bool ApplyState (int newSelectionIndex, bool stateAtThisObject)
protected override void ApplyState (int newSelectionIndex, bool stateAtThisObject)
{
selectionIndex = -1;

if (!CheckListItemBeforeUpdate (newSelectionIndex)) return false;
if (!CheckListItemBeforeUpdate (newSelectionIndex)) return;

subStateMachines[newSelectionIndex].UpdateState (stateAtThisObject);

return true;
}

/// <summary>
Expand All @@ -79,22 +70,19 @@ protected override bool ApplyState (int newSelectionIndex, bool stateAtThisObjec
/// <param name="startIndex">Where to start applying your state (inclusive).</param>
/// <param name="length">How many objects to affect.</param>
/// <param name="stateToApply">The state to apply within your given range.</param>
/// <returns>Whether or not the operation succeeded.</returns>
protected override bool ApplyState (int startIndex, int length, bool stateToApply)
protected override void ApplyState (int startIndex, int length, bool stateToApply)
{
selectionIndex = -1;

for (int i = 0; i < subStateMachines.Count; i++)
{
if (!CheckListItemBeforeUpdate (i)) return false;
if (!CheckListItemBeforeUpdate (i)) return;

if (i >= startIndex && i < startIndex + length)
subStateMachines[i].UpdateState (stateToApply);
else
subStateMachines[i].UpdateState (!stateToApply);
}

return true;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ public void AddToList (int instances)
[Test]
public void UpdateStateSuccess ()
{
Assert.True (stateMachine.UpdateState (1));
stateMachine.UpdateState (1);
Assert.True (!gameObjects[0].activeSelf && gameObjects[1].activeSelf && !gameObjects[2].activeSelf);
}

[Test]
Expand Down Expand Up @@ -79,7 +80,8 @@ public void UpdateStateWithOutOfRangeIndex ()
[Test]
public void UpdateStateWithSameIndex ()
{
Assert.True (stateMachine.UpdateState (0));
stateMachine.UpdateState (0);
Assert.True (gameObjects[0].activeSelf && !gameObjects[1].activeSelf && !gameObjects[2].activeSelf);
}

[Test]
Expand Down Expand Up @@ -128,7 +130,8 @@ public void AddToList (int instances)
[Test]
public void UpdateStateSuccess ()
{
Assert.True (stateMachine.UpdateState (true));
stateMachine.UpdateState (true);
Assert.True (gameObjects[0].activeSelf && gameObjects[1].activeSelf && gameObjects[2].activeSelf);
}

[Test]
Expand Down Expand Up @@ -193,7 +196,8 @@ public void AddToList (int instances)
[Test]
public void UpdateStateSuccess ()
{
Assert.True (stateMachine.UpdateState (1, true));
stateMachine.UpdateState (1, true);
Assert.True (gameObjects[0].activeSelf && gameObjects[1].activeSelf && !gameObjects[2].activeSelf);
}

[Test]
Expand Down Expand Up @@ -229,7 +233,8 @@ public void UpdateStateToggle ()
[Test]
public void UpdateStateWithSameIndex ()
{
Assert.True (stateMachine.UpdateState (0, true));
stateMachine.UpdateState (0, true);
Assert.True (gameObjects[0].activeSelf && !gameObjects[1].activeSelf && !gameObjects[2].activeSelf);
}

[Test]
Expand Down Expand Up @@ -291,7 +296,8 @@ public void AddToList (int instances)
[Test]
public void UpdateStateSuccess ()
{
Assert.True (stateMachine.UpdateState (1, 2, true));
stateMachine.UpdateState (1, 2, true);
Assert.True (!gameObjects[0].activeSelf && gameObjects[1].activeSelf && gameObjects[2].activeSelf);
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "com.open.scriptable-framework",
"displayName": "Scriptable Framework",
"author": "Jak Hussain, Dean Giddy, Conor Galvin",
"version": "1.2.4",
"version": "1.2.5",
"unity": "2018.3",
"description": "A modularity framework developed to better enable Unity developers to decouple and test their code using ScriptableObject based dependencies that can be dragged and dropped into the inspector. The API and workflow makes it easy to use advanced programming patterns and SOLID principals in your projects which promotes a higher quality of code.The Scriptable Framework is the core of all future module development for Arup. See GitHub for documentation.",
"keywords": [
Expand Down
10 changes: 9 additions & 1 deletion docfx/articles/State Machines/usingStateMachines.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,12 @@ Because of the execution order of what goes on with Scriptable Framework behind

![Figure2](~/images/stateMachines2.png)

**NOTE**: It is much quicker to use a populator to set the references in your GameObjectList automatically rather than to write your own code for it. See the Populators manual for further details.
**NOTE**: It is much quicker to use a populator to set the references in your GameObjectList automatically rather than to write your own code for it. See the Populators manual for further details.

## StateMachines via UI Components

Traditionally, a UI component like a button or a dropdown would have an instance of a MonoBehaviour dragged into them so that one of its methods could be assigned for the UI object to invoke. What most people don't know is, you can also do this with ScriptableObjects!

![Figure3](~/images/stateMachines3.png)

The image above shows an example of how a dropdown component has a StateMachine assigned to its object reference. By doing this, you can call the `UpdateState` method directly from the UI and not write any code at all for controlling objects in your scene.
Binary file added docfx/images/stateMachines3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 9f54f10

Please sign in to comment.