From fb0b9ff77e3f12212a087000ae2d6c74dabee722 Mon Sep 17 00:00:00 2001
From: rqchia <raymond.q.chia@student.uts.edu.au>
Date: Wed, 8 Nov 2023 14:22:50 +1100
Subject: [PATCH] additional runtime and blockstack feature

---
 Assets/Prefab/BlockObject.prefab           |  55 ++-
 Assets/ProtocolHandler.cs                  |  59 +++
 Assets/ProtocolHandler.cs.meta             |  11 +
 Assets/Scenes/Menu.unity                   | 425 +++++++++++++++++++--
 Assets/Scripts/AnimateCircle.cs            |  84 ++--
 Assets/Scripts/BlockHandler.cs             | 106 +++--
 Assets/Scripts/BlockObjectClass.cs         |  69 ++++
 Assets/Scripts/BlockObjectClass.cs.meta    |  11 +
 Assets/Scripts/DisplayRuntimeValue.cs      |  32 ++
 Assets/Scripts/DisplayRuntimeValue.cs.meta |  11 +
 10 files changed, 734 insertions(+), 129 deletions(-)
 create mode 100644 Assets/ProtocolHandler.cs
 create mode 100644 Assets/ProtocolHandler.cs.meta
 create mode 100644 Assets/Scripts/BlockObjectClass.cs
 create mode 100644 Assets/Scripts/BlockObjectClass.cs.meta
 create mode 100644 Assets/Scripts/DisplayRuntimeValue.cs
 create mode 100644 Assets/Scripts/DisplayRuntimeValue.cs.meta

diff --git a/Assets/Prefab/BlockObject.prefab b/Assets/Prefab/BlockObject.prefab
index a61e9d4..80c02f9 100644
--- a/Assets/Prefab/BlockObject.prefab
+++ b/Assets/Prefab/BlockObject.prefab
@@ -480,7 +480,19 @@ MonoBehaviour:
   m_CharacterLimit: 0
   m_OnEndEdit:
     m_PersistentCalls:
-      m_Calls: []
+      m_Calls:
+      - m_Target: {fileID: 7667070743931665524}
+        m_TargetAssemblyTypeName: BlockObjectClass, Assembly-CSharp
+        m_MethodName: SetInhalePeriod
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
   m_OnSubmit:
     m_PersistentCalls:
       m_Calls: []
@@ -708,7 +720,19 @@ MonoBehaviour:
   m_CharacterLimit: 0
   m_OnEndEdit:
     m_PersistentCalls:
-      m_Calls: []
+      m_Calls:
+      - m_Target: {fileID: 7667070743931665524}
+        m_TargetAssemblyTypeName: BlockObjectClass, Assembly-CSharp
+        m_MethodName: SetRuntime
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
   m_OnSubmit:
     m_PersistentCalls:
       m_Calls: []
@@ -940,6 +964,7 @@ GameObject:
   serializedVersion: 6
   m_Component:
   - component: {fileID: 4469486358827566908}
+  - component: {fileID: 7667070743931665524}
   m_Layer: 0
   m_Name: BlockObject
   m_TagString: Untagged
@@ -965,6 +990,18 @@ Transform:
   - {fileID: 6585179749909385394}
   m_Father: {fileID: 0}
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &7667070743931665524
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 5953652883336373052}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 6632b785cc731fa4996c86370c8222be, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
 --- !u!1 &6199854548257288693
 GameObject:
   m_ObjectHideFlags: 0
@@ -1548,7 +1585,19 @@ MonoBehaviour:
   m_CharacterLimit: 0
   m_OnEndEdit:
     m_PersistentCalls:
-      m_Calls: []
+      m_Calls:
+      - m_Target: {fileID: 7667070743931665524}
+        m_TargetAssemblyTypeName: BlockObjectClass, Assembly-CSharp
+        m_MethodName: SetExhalePeriod
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
   m_OnSubmit:
     m_PersistentCalls:
       m_Calls: []
diff --git a/Assets/ProtocolHandler.cs b/Assets/ProtocolHandler.cs
new file mode 100644
index 0000000..0541dd9
--- /dev/null
+++ b/Assets/ProtocolHandler.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using TMPro;
+
+public class ProtocolHandler : MonoBehaviour
+{
+    public GameObject numCyclesInput;
+    public GameObject blockControl;
+    public float TotalRuntime { get; private set; }
+
+    BlockHandler blockHandler;
+    List<GameObject> blockStack = new List<GameObject>();
+    int nCycles = 1;
+    int currentBlockIndex = 0;
+    int currentCycle = 0;
+
+    float timeBetweenBlocks = 3f; // seconds, not implemented
+    
+    // Start is called before the first frame update
+    void Start()
+    {
+        UpdateTotalRuntime();
+    }
+
+    // Update is called once per frame
+    void Update()
+    {
+
+    }
+
+    // Update runtime by adding each block runtime, adding 3s for each block,
+    // and multiplying by cycles
+    public void UpdateTotalRuntime()
+    {
+        blockHandler = blockControl.GetComponent<BlockHandler>();
+        TotalRuntime = blockHandler.blockStackRuntime;
+        TotalRuntime *= nCycles;
+    }
+
+    public void UpdateNumCycles()
+    {
+        TMP_InputField inputField = numCyclesInput.GetComponent<TMP_InputField>();
+        nCycles = (int)Convert.ToInt32(inputField.text);
+    }
+
+    public void SetBlockStack()
+    {
+        blockStack = blockHandler.GetBlockStack();
+        int i = 0;
+        foreach (var block in blockStack)
+        {
+            BlockObjectClass boc = block.GetComponent<BlockObjectClass>();
+            Debug.Log("boc " + i + " inhale: " + boc.InhalePeriod);
+            i++;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Assets/ProtocolHandler.cs.meta b/Assets/ProtocolHandler.cs.meta
new file mode 100644
index 0000000..e6bab8d
--- /dev/null
+++ b/Assets/ProtocolHandler.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4086a0d1049524d4ca4421406fc81727
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scenes/Menu.unity b/Assets/Scenes/Menu.unity
index c26ff27..0417ce1 100644
--- a/Assets/Scenes/Menu.unity
+++ b/Assets/Scenes/Menu.unity
@@ -919,12 +919,13 @@ RectTransform:
   m_ConstrainProportionsScale: 0
   m_Children:
   - {fileID: 1380266463}
+  - {fileID: 1447497996}
   m_Father: {fileID: 473153907}
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
   m_AnchorMin: {x: 0.5, y: 0.5}
   m_AnchorMax: {x: 0.5, y: 0.5}
-  m_AnchoredPosition: {x: -248.49, y: -156.7}
-  m_SizeDelta: {x: 271.8068, y: 35}
+  m_AnchoredPosition: {x: -189.6, y: -153.38106}
+  m_SizeDelta: {x: 231.9795, y: 28.3621}
   m_Pivot: {x: 0.5, y: 0.5}
 --- !u!114 &559601517
 MonoBehaviour:
@@ -973,8 +974,8 @@ MonoBehaviour:
   m_faceColor:
     serializedVersion: 2
     rgba: 4294967295
-  m_fontSize: 24
-  m_fontSizeBase: 24
+  m_fontSize: 22
+  m_fontSizeBase: 22
   m_fontWeight: 400
   m_enableAutoSizing: 0
   m_fontSizeMin: 18
@@ -1589,6 +1590,52 @@ CanvasRenderer:
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 828931910}
   m_CullTransparentMesh: 1
+--- !u!1 &869075939
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 869075941}
+  - component: {fileID: 869075940}
+  m_Layer: 0
+  m_Name: ProtocolHandler
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &869075940
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 869075939}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 4086a0d1049524d4ca4421406fc81727, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  numCyclesInput: {fileID: 1992066360}
+  blockControl: {fileID: 1785070519}
+--- !u!4 &869075941
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 869075939}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 629.43994, y: 438.92883, z: -6.8732853}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
 --- !u!1 &1113057184
 GameObject:
   m_ObjectHideFlags: 0
@@ -1823,24 +1870,6 @@ MonoBehaviour:
   m_GlobalPointSize: 14
   m_CharacterLimit: 0
   m_OnEndEdit:
-    m_PersistentCalls:
-      m_Calls: []
-  m_OnSubmit:
-    m_PersistentCalls:
-      m_Calls: []
-  m_OnSelect:
-    m_PersistentCalls:
-      m_Calls: []
-  m_OnDeselect:
-    m_PersistentCalls:
-      m_Calls: []
-  m_OnTextSelection:
-    m_PersistentCalls:
-      m_Calls: []
-  m_OnEndTextSelection:
-    m_PersistentCalls:
-      m_Calls: []
-  m_OnValueChanged:
     m_PersistentCalls:
       m_Calls:
       - m_Target: {fileID: 1785070524}
@@ -1869,7 +1898,7 @@ MonoBehaviour:
         m_CallState: 2
       - m_Target: {fileID: 1785070524}
         m_TargetAssemblyTypeName: BlockHandler, Assembly-CSharp
-        m_MethodName: UpdateBlockObjects
+        m_MethodName: UpdateBlockStack
         m_Mode: 1
         m_Arguments:
           m_ObjectArgument: {fileID: 0}
@@ -1879,6 +1908,24 @@ MonoBehaviour:
           m_StringArgument: 
           m_BoolArgument: 0
         m_CallState: 2
+  m_OnSubmit:
+    m_PersistentCalls:
+      m_Calls: []
+  m_OnSelect:
+    m_PersistentCalls:
+      m_Calls: []
+  m_OnDeselect:
+    m_PersistentCalls:
+      m_Calls: []
+  m_OnTextSelection:
+    m_PersistentCalls:
+      m_Calls: []
+  m_OnEndTextSelection:
+    m_PersistentCalls:
+      m_Calls: []
+  m_OnValueChanged:
+    m_PersistentCalls:
+      m_Calls: []
   m_OnTouchScreenKeyboardStatusChanged:
     m_PersistentCalls:
       m_Calls: []
@@ -2302,6 +2349,7 @@ GameObject:
   - component: {fileID: 1380266463}
   - component: {fileID: 1380266465}
   - component: {fileID: 1380266464}
+  - component: {fileID: 1380266466}
   m_Layer: 5
   m_Name: RuntimeValue
   m_TagString: Untagged
@@ -2348,7 +2396,7 @@ MonoBehaviour:
   m_OnCullStateChanged:
     m_PersistentCalls:
       m_Calls: []
-  m_text: 1
+  m_text: 
   m_isRightToLeft: 0
   m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
   m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
@@ -2425,6 +2473,19 @@ CanvasRenderer:
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 1380266462}
   m_CullTransparentMesh: 1
+--- !u!114 &1380266466
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1380266462}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 379892acc53108d45bdbe28f2e3223fd, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  protocolGameObject: {fileID: 869075939}
 --- !u!1 &1380475412
 GameObject:
   m_ObjectHideFlags: 0
@@ -2716,6 +2777,163 @@ CanvasRenderer:
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 1412809335}
   m_CullTransparentMesh: 1
+--- !u!1 &1447497995
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1447497996}
+  - component: {fileID: 1447497999}
+  - component: {fileID: 1447497998}
+  - component: {fileID: 1447497997}
+  m_Layer: 5
+  m_Name: RuntimeUpdate
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1447497996
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1447497995}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children:
+  - {fileID: 1508149527}
+  m_Father: {fileID: 559601516}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0.5, y: 0.5}
+  m_AnchorMax: {x: 0.5, y: 0.5}
+  m_AnchoredPosition: {x: -165.5, y: 0.81895}
+  m_SizeDelta: {x: 80, y: 30}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1447497997
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1447497995}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Navigation:
+    m_Mode: 3
+    m_WrapAround: 0
+    m_SelectOnUp: {fileID: 0}
+    m_SelectOnDown: {fileID: 0}
+    m_SelectOnLeft: {fileID: 0}
+    m_SelectOnRight: {fileID: 0}
+  m_Transition: 1
+  m_Colors:
+    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+    m_ColorMultiplier: 1
+    m_FadeDuration: 0.1
+  m_SpriteState:
+    m_HighlightedSprite: {fileID: 0}
+    m_PressedSprite: {fileID: 0}
+    m_SelectedSprite: {fileID: 0}
+    m_DisabledSprite: {fileID: 0}
+  m_AnimationTriggers:
+    m_NormalTrigger: Normal
+    m_HighlightedTrigger: Highlighted
+    m_PressedTrigger: Pressed
+    m_SelectedTrigger: Selected
+    m_DisabledTrigger: Disabled
+  m_Interactable: 1
+  m_TargetGraphic: {fileID: 1447497998}
+  m_OnClick:
+    m_PersistentCalls:
+      m_Calls:
+      - m_Target: {fileID: 1785070524}
+        m_TargetAssemblyTypeName: BlockHandler, Assembly-CSharp
+        m_MethodName: UpdateBlockStackRuntime
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
+      - m_Target: {fileID: 869075940}
+        m_TargetAssemblyTypeName: ProtocolHandler, Assembly-CSharp
+        m_MethodName: UpdateTotalRuntime
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
+      - m_Target: {fileID: 1380266466}
+        m_TargetAssemblyTypeName: DisplayRuntimeValue, Assembly-CSharp
+        m_MethodName: DisplayRuntime
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
+--- !u!114 &1447497998
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1447497995}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
+  m_Type: 1
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!222 &1447497999
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1447497995}
+  m_CullTransparentMesh: 1
 --- !u!1 &1472655368
 GameObject:
   m_ObjectHideFlags: 0
@@ -2829,6 +3047,140 @@ CanvasRenderer:
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 1488171488}
   m_CullTransparentMesh: 1
+--- !u!1 &1508149526
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1508149527}
+  - component: {fileID: 1508149529}
+  - component: {fileID: 1508149528}
+  m_Layer: 5
+  m_Name: Text (TMP)
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1508149527
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1508149526}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 1447497996}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1508149528
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1508149526}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 1
+  m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_text: Update
+  m_isRightToLeft: 0
+  m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
+  m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
+  m_fontSharedMaterials: []
+  m_fontMaterial: {fileID: 0}
+  m_fontMaterials: []
+  m_fontColor32:
+    serializedVersion: 2
+    rgba: 4281479730
+  m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
+  m_enableVertexGradient: 0
+  m_colorMode: 3
+  m_fontColorGradient:
+    topLeft: {r: 1, g: 1, b: 1, a: 1}
+    topRight: {r: 1, g: 1, b: 1, a: 1}
+    bottomLeft: {r: 1, g: 1, b: 1, a: 1}
+    bottomRight: {r: 1, g: 1, b: 1, a: 1}
+  m_fontColorGradientPreset: {fileID: 0}
+  m_spriteAsset: {fileID: 0}
+  m_tintAllSprites: 0
+  m_StyleSheet: {fileID: 0}
+  m_TextStyleHashCode: -1183493901
+  m_overrideHtmlColors: 0
+  m_faceColor:
+    serializedVersion: 2
+    rgba: 4294967295
+  m_fontSize: 18
+  m_fontSizeBase: 18
+  m_fontWeight: 400
+  m_enableAutoSizing: 0
+  m_fontSizeMin: 18
+  m_fontSizeMax: 72
+  m_fontStyle: 0
+  m_HorizontalAlignment: 2
+  m_VerticalAlignment: 512
+  m_textAlignment: 65535
+  m_characterSpacing: 0
+  m_wordSpacing: 0
+  m_lineSpacing: 0
+  m_lineSpacingMax: 0
+  m_paragraphSpacing: 0
+  m_charWidthMaxAdj: 0
+  m_enableWordWrapping: 1
+  m_wordWrappingRatios: 0.4
+  m_overflowMode: 0
+  m_linkedTextComponent: {fileID: 0}
+  parentLinkedComponent: {fileID: 0}
+  m_enableKerning: 1
+  m_enableExtraPadding: 0
+  checkPaddingRequired: 0
+  m_isRichText: 1
+  m_parseCtrlCharacters: 1
+  m_isOrthographic: 1
+  m_isCullingEnabled: 0
+  m_horizontalMapping: 0
+  m_verticalMapping: 0
+  m_uvLineOffset: 0
+  m_geometrySortingOrder: 0
+  m_IsTextObjectScaleStatic: 0
+  m_VertexBufferAutoSizeReduction: 0
+  m_useMaxVisibleDescender: 1
+  m_pageToDisplay: 1
+  m_margin: {x: 0, y: 0, z: 0, w: 0}
+  m_isUsingLegacyAnimationComponent: 0
+  m_isVolumetricText: 0
+  m_hasFontAssetChanged: 0
+  m_baseMaterial: {fileID: 0}
+  m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
+--- !u!222 &1508149529
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1508149526}
+  m_CullTransparentMesh: 1
 --- !u!1 &1534377887
 GameObject:
   m_ObjectHideFlags: 0
@@ -3277,11 +3629,11 @@ MonoBehaviour:
       - m_Target: {fileID: 1785070524}
         m_TargetAssemblyTypeName: BlockHandler, Assembly-CSharp
         m_MethodName: SetRunningBlockIndex
-        m_Mode: 1
+        m_Mode: 3
         m_Arguments:
           m_ObjectArgument: {fileID: 0}
           m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
-          m_IntArgument: 0
+          m_IntArgument: -1
           m_FloatArgument: 0
           m_StringArgument: 
           m_BoolArgument: 0
@@ -3361,8 +3713,8 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: 543dae1d77f653d4fa1fef234513a4ca, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
-  nblock_input: {fileID: 1166148096}
-  block_object: {fileID: 5953652883336373052, guid: 33940c6653f8c7743a09e6d66a285ead, type: 3}
+  nBlockInput: {fileID: 1166148096}
+  blockObject: {fileID: 5953652883336373052, guid: 33940c6653f8c7743a09e6d66a285ead, type: 3}
   animateCircle: {fileID: 1953068991}
 --- !u!1 &1875542612
 GameObject:
@@ -3755,7 +4107,7 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: 90fe0aef7f0c12d4a9073232e5cfa2b1, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
-  block_obj: {fileID: 5953652883336373052, guid: 33940c6653f8c7743a09e6d66a285ead, type: 3}
+  blockObj: {fileID: 5953652883336373052, guid: 33940c6653f8c7743a09e6d66a285ead, type: 3}
 --- !u!1 &1992066360
 GameObject:
   m_ObjectHideFlags: 0
@@ -3857,7 +4209,19 @@ MonoBehaviour:
   m_CharacterLimit: 0
   m_OnEndEdit:
     m_PersistentCalls:
-      m_Calls: []
+      m_Calls:
+      - m_Target: {fileID: 869075940}
+        m_TargetAssemblyTypeName: ProtocolHandler, Assembly-CSharp
+        m_MethodName: UpdateNumCycles
+        m_Mode: 1
+        m_Arguments:
+          m_ObjectArgument: {fileID: 0}
+          m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
+          m_IntArgument: 0
+          m_FloatArgument: 0
+          m_StringArgument: 
+          m_BoolArgument: 0
+        m_CallState: 2
   m_OnSubmit:
     m_PersistentCalls:
       m_Calls: []
@@ -4163,3 +4527,4 @@ SceneRoots:
   - {fileID: 1912239089}
   - {fileID: 473153907}
   - {fileID: 2036898558}
+  - {fileID: 869075941}
diff --git a/Assets/Scripts/AnimateCircle.cs b/Assets/Scripts/AnimateCircle.cs
index b8d600d..3aa6386 100644
--- a/Assets/Scripts/AnimateCircle.cs
+++ b/Assets/Scripts/AnimateCircle.cs
@@ -6,26 +6,27 @@ using TMPro;
 
 public class AnimateCircle : MonoBehaviour
 {
-    public GameObject block_obj;
+    public GameObject blockObj;
 
-    float inhale_period = 0f;
-    float exhale_period = 0f;
-    float max_runtime = 0f;
+    BlockObjectClass blockObjectClass;
+    float inhalePeriod = 0f;
+    float exhalePeriod = 0f;
+    float maxRuntime = 0f;
     float runtime = 0f;
 
     private bool is_inhale; /* 1 if inhalation, 0 if exhaltion */
-    private Vector3 scale_diff = new Vector3(0.9f, 0.9f, 0.0f);
-    private Vector3 original_scale = new Vector3(0.1f, 0.1f, 0.0f);
-    private Vector3 final_scale = new Vector3(0.98f, 0.98f, 0.0f);
-    private Vector3 inhale_velocity = new Vector3(0.0f, 0.0f, 0.0f);
-    private Vector3 exhale_velocity = new Vector3(0.0f, 0.0f, 0.0f);
+    private Vector3 scaleDiff = new Vector3(0.9f, 0.9f, 0.0f);
+    private Vector3 originalScale = new Vector3(0.1f, 0.1f, 0.0f);
+    private Vector3 finalScale = new Vector3(0.98f, 0.98f, 0.0f);
+    private Vector3 inhaleVelocity = new Vector3(0.0f, 0.0f, 0.0f);
+    private Vector3 exhaleVelocity = new Vector3(0.0f, 0.0f, 0.0f);
 
     // Start is called before the first frame update
     void Start()
     {
         is_inhale = true;
-        original_scale = this.transform.localScale;
-        scale_diff = final_scale - original_scale;
+        originalScale = this.transform.localScale;
+        scaleDiff = finalScale - originalScale;
 
         StateReset();
         this.enabled = false;
@@ -62,83 +63,50 @@ public class AnimateCircle : MonoBehaviour
     {
         SetPeriod();
         SetMaxRuntime();
-        inhale_velocity = scale_diff / inhale_period;
-        exhale_velocity = scale_diff / exhale_period;
-        this.transform.localScale = original_scale;
+        inhaleVelocity = scaleDiff / inhalePeriod;
+        exhaleVelocity = scaleDiff / exhalePeriod;
+        this.transform.localScale = originalScale;
         runtime = 0f;
     }
 
     void SetPeriod()
     {
-        string name;
-        GameObject go;
-        TMP_InputField input_field;
-        Transform[] transforms = block_obj.GetComponentsInChildren<Transform>();
-
-        foreach (var transform in transforms)
-        {
-            go = transform.gameObject;
-            name = go.name;
-            if (name == "Inhale")
-            {
-                input_field = go.GetComponent<TMP_InputField>();
-                inhale_period = (float) Convert.ToDouble(input_field.text);
-            }
-            else if (name == "Exhale")
-            {
-                input_field = go.GetComponent<TMP_InputField>();
-                exhale_period = (float) Convert.ToDouble(input_field.text);
-            }
-        }
-        Debug.Log("inhale: " + inhale_period);
-        Debug.Log("exhale: " + exhale_period);
+        blockObjectClass = blockObj.GetComponent<BlockObjectClass>();
+        inhalePeriod = blockObjectClass.InhalePeriod;
+        exhalePeriod = blockObjectClass.ExhalePeriod;
     }
     void SetMaxRuntime()
     {
-        string name;
-        GameObject go;
-        TMP_InputField input_field;
-        Transform[] transforms = block_obj.GetComponentsInChildren<Transform>();
-
-        foreach (var transform in transforms)
-        {
-            go = transform.gameObject;
-            name = go.name;
-            if (name == "Runtime")
-            {
-                input_field = go.GetComponent<TMP_InputField>();
-                max_runtime = (float) Convert.ToDouble(input_field.text) * 60;
-            }
-        }
-        Debug.Log("runtime: " + max_runtime);
+        blockObjectClass = blockObj.GetComponent<BlockObjectClass>();
+        maxRuntime = blockObjectClass.MaxRuntime;
     }
 
     void UpdateInhaleScale()
     {
         float dt = Time.deltaTime;
         Vector3 scale = this.transform.localScale;
-        this.transform.localScale = inhale_velocity*dt + scale;
+        this.transform.localScale = inhaleVelocity*dt + scale;
     }
 
     void UpdateExhaleScale()
     {
         float dt = Time.deltaTime;
         Vector3 scale = this.transform.localScale;
-        this.transform.localScale = -exhale_velocity*dt + scale;
+        this.transform.localScale = -exhaleVelocity*dt + scale;
     }
 
     void UpdateRespState()
     {
         Vector3 scale = this.transform.localScale;
-        if(scale.x >= final_scale.x | scale.x <= original_scale.x)
+        if(scale.x >= finalScale.x | scale.x <= originalScale.x)
         {
             if (is_inhale)
             {
-                this.transform.localScale = final_scale;
+                this.transform.localScale = finalScale;
             }
             else
             {
-                this.transform.localScale = original_scale;
+                this.transform.localScale = originalScale;
             }
             is_inhale = !is_inhale;
         }
@@ -146,7 +114,7 @@ public class AnimateCircle : MonoBehaviour
 
     void UpdateRuntimeState()
     {
-        if (runtime >= max_runtime)
+        if (runtime >= maxRuntime)
         {
             StateReset();
             this.enabled = false;
diff --git a/Assets/Scripts/BlockHandler.cs b/Assets/Scripts/BlockHandler.cs
index 00f9cc9..34b49a0 100644
--- a/Assets/Scripts/BlockHandler.cs
+++ b/Assets/Scripts/BlockHandler.cs
@@ -7,29 +7,31 @@ using TMPro;
 
 public class BlockHandler : MonoBehaviour
 {
-    public GameObject nblock_input;
-    public GameObject block_object;
+    public GameObject nBlockInput;
+    public GameObject blockObject;
     public AnimateCircle animateCircle;
-    public int max_num_blocks { get; private set; }
+    public int maxNumBlocks { get; private set; }
+    public float blockStackRuntime { get; private set; }
 
     TMP_Dropdown dropdown;
-    List<GameObject> block_objects = new List<GameObject>();
-    GameObject running_block;
-    int current_block_index = 0;
+    List<GameObject> blockStack = new List<GameObject>();
+    GameObject runningBlock;
+    int currentBlockIndex = 0;
 
-    private Vector3 block_home_position = new Vector3(-104f, -345f, 0f);
+    private Vector3 blockHomePosition = new Vector3(-104f, -345f, 0f);
     // Start is called before the first frame update
-    void Start()
+    void Awake()
     {
         dropdown = this.GetComponent<TMP_Dropdown>();
-        GameObject first_block = GetBlockObjectPrefab();
-        block_objects.Add(first_block);
-        block_objects[0].SetActive(true);
-        running_block = block_objects[0];
+        GameObject firstBlock = GetBlockObjectPrefab();
+        blockStack.Add(firstBlock);
+        blockStack[0].SetActive(true);
+        runningBlock = blockStack[0];
 
         UpdateOptions();
         SetRunningBlockIndex();
         UpdateRunningBlock();
+        UpdateBlockStackRuntime();
     }
 
     // Update is called once per frame
@@ -42,7 +44,7 @@ public class BlockHandler : MonoBehaviour
     {
         UpdateMaxNumBlocks();
         dropdown.ClearOptions();
-        for (int i = 1; i < max_num_blocks + 1; i++)
+        for (int i = 1; i < maxNumBlocks + 1; i++)
         {
             dropdown.AddOptions(new List<string> { i.ToString() });
         }
@@ -50,67 +52,95 @@ public class BlockHandler : MonoBehaviour
 
     public void UpdateMaxNumBlocks()
     { 
-        TMP_InputField input_field;
-        input_field = nblock_input.GetComponent<TMP_InputField>();
-        max_num_blocks = Int32.Parse(input_field.text);
+        TMP_InputField inputField;
+        inputField = nBlockInput.GetComponent<TMP_InputField>();
+        maxNumBlocks = Int32.Parse(inputField.text);
+        if (maxNumBlocks <= 0)
+        {
+            maxNumBlocks = 1;
+        }        
     }
 
-    public void SetRunningBlockIndex()
+    public void SetRunningBlockIndex(int blockIndexInput = -1)
     {
-        current_block_index = dropdown.value;
-        Debug.Log("current block index: " + current_block_index);
+        if (blockIndexInput == -1)
+        {
+            currentBlockIndex = dropdown.value;
+        }
+        else
+        {
+            currentBlockIndex = blockIndexInput;
+        }
+        Debug.Log("current block index: " + currentBlockIndex);
     }
 
-    public void UpdateBlockObjects()
+    public void UpdateBlockStack()
     {
-        bool is_empty = !block_objects.Any();
-        int num_block_objects = 0;
-        if (!is_empty)
+        bool isEmpty = !blockStack.Any();
+        int numblockStack = 0;
+        if (!isEmpty)
         {
-            num_block_objects = block_objects.Count;
+            numblockStack = blockStack.Count;
         }
-        if (max_num_blocks > num_block_objects)
+        if (maxNumBlocks > numblockStack)
         {
-            for (int i = num_block_objects; i < max_num_blocks; i++)
+            for (int i = numblockStack; i < maxNumBlocks; i++)
             {
-                block_objects.Add(GetBlockObjectPrefab());
-                block_objects[i].SetActive(false);
+                blockStack.Add(GetBlockObjectPrefab());
+                blockStack[i].SetActive(false);
             }
         }
-        else if (max_num_blocks < num_block_objects)
+        else if (maxNumBlocks < numblockStack)
         {
-            for (int i = num_block_objects; i > max_num_blocks; i--)
+            for (int i = numblockStack; i > maxNumBlocks; i--)
             {
-                block_objects.RemoveAt(i);
+                blockStack.RemoveAt(i);
             }
         }
-        current_block_index = 0;
+        SetRunningBlockIndex();
         SetRunningBlock();
         UpdateRunningBlock();
+        UpdateBlockStackRuntime();
     }
 
     public void SetRunningBlock()
     {
-        running_block.SetActive(false);
-        running_block = block_objects[current_block_index];
-        running_block.SetActive(true);
+        runningBlock.SetActive(false);
+        runningBlock = blockStack[currentBlockIndex];
+        runningBlock.SetActive(true);
     }
 
     public void UpdateRunningBlock()
     {
-        animateCircle.block_obj = running_block;
+        animateCircle.blockObj = runningBlock;
+    }
+
+    public List<GameObject> GetBlockStack()
+    {
+        return blockStack;
+    }
+
+    public void UpdateBlockStackRuntime()
+    {
+        blockStackRuntime = 0;
+        foreach (var blockObject in blockStack)
+        {
+            BlockObjectClass blockObjectClass = blockObject.GetComponent<BlockObjectClass>();
+            blockStackRuntime += blockObjectClass.MaxRuntime;
+        }
     }
 
     GameObject GetBlockObjectPrefab()
     {
         GameObject block = Instantiate(
-            block_object,
+            blockObject,
             new Vector3(0f, 0f, 0f),
             Quaternion.identity
             );
         block.transform.parent = this.transform;
-        block.transform.localPosition = block_home_position;
+        block.transform.localPosition = blockHomePosition;
         block.transform.localScale = new Vector3(1f, 1f, 0f);
         return block;
     }
+
 }
diff --git a/Assets/Scripts/BlockObjectClass.cs b/Assets/Scripts/BlockObjectClass.cs
new file mode 100644
index 0000000..daf4b0a
--- /dev/null
+++ b/Assets/Scripts/BlockObjectClass.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using TMPro;
+
+public class BlockObjectClass : MonoBehaviour
+{
+    public float InhalePeriod { get; private set; }
+    public float ExhalePeriod { get; private set; }
+    public float MaxRuntime { get; private set; }
+
+    TMP_InputField inhalePeriodInput;
+    TMP_InputField exhalePeriodInput;
+    TMP_InputField runtimeInput;
+
+    void Awake()
+    {
+        string name;
+        GameObject go;
+        Transform[] transforms = this.GetComponentsInChildren<Transform>();
+
+        foreach (var transform in transforms)
+        {
+            go = transform.gameObject;
+            name = go.name;
+            if (name == "Inhale")
+            {
+                inhalePeriodInput = go.GetComponent<TMP_InputField>();
+                SetInhalePeriod();
+            }
+            else if (name == "Exhale")
+            {
+                exhalePeriodInput = go.GetComponent<TMP_InputField>();
+                SetExhalePeriod();
+            }
+            else if (name == "Runtime")
+            {
+                runtimeInput = go.GetComponent<TMP_InputField>();
+                SetRuntime();
+            }
+        }
+    }
+
+    // Start is called before the first frame update
+    void Start()
+    {
+
+    }
+
+    // Update is called once per frame
+    void Update()
+    {
+        
+    }
+
+    public void SetInhalePeriod()
+    {
+        InhalePeriod = (float)Convert.ToDouble(inhalePeriodInput.text);
+    }
+    public void SetExhalePeriod()
+    {
+        ExhalePeriod = (float)Convert.ToDouble(exhalePeriodInput.text);
+    }
+    public void SetRuntime()
+    {
+        MaxRuntime = (float)Convert.ToDouble(runtimeInput.text)*60;
+    }
+}
diff --git a/Assets/Scripts/BlockObjectClass.cs.meta b/Assets/Scripts/BlockObjectClass.cs.meta
new file mode 100644
index 0000000..b5959df
--- /dev/null
+++ b/Assets/Scripts/BlockObjectClass.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6632b785cc731fa4996c86370c8222be
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/DisplayRuntimeValue.cs b/Assets/Scripts/DisplayRuntimeValue.cs
new file mode 100644
index 0000000..adfb70f
--- /dev/null
+++ b/Assets/Scripts/DisplayRuntimeValue.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using TMPro;
+
+public class DisplayRuntimeValue : MonoBehaviour
+{
+    public GameObject protocolGameObject;
+
+    ProtocolHandler protocolHandler;
+    float runtimeMinutes = 1;
+    // Start is called before the first frame update
+    void Start()
+    {
+        protocolHandler = protocolGameObject.GetComponent<ProtocolHandler>();
+    }
+
+    // Update is called once per frame
+    void Update()
+    {
+
+    }
+
+    public void DisplayRuntime()
+    {
+        TMP_Text displayText = this.GetComponent<TMP_Text>();
+        runtimeMinutes = protocolHandler.TotalRuntime / 60;
+        string text = runtimeMinutes.ToString();
+        displayText.SetText(text);
+    }
+}
diff --git a/Assets/Scripts/DisplayRuntimeValue.cs.meta b/Assets/Scripts/DisplayRuntimeValue.cs.meta
new file mode 100644
index 0000000..d365f53
--- /dev/null
+++ b/Assets/Scripts/DisplayRuntimeValue.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 379892acc53108d45bdbe28f2e3223fd
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
-- 
GitLab