172 lines
6.1 KiB
C#
172 lines
6.1 KiB
C#
|
//============= Copyright (c) Ludic GmbH, All rights reserved. ==============
|
|||
|
//
|
|||
|
// Purpose: Part of the My Behaviour Tree Code
|
|||
|
//
|
|||
|
//=============================================================================
|
|||
|
|
|||
|
using System;
|
|||
|
using System.Collections;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Xml.Serialization;
|
|||
|
using UnityEngine;
|
|||
|
|
|||
|
namespace MyBT {
|
|||
|
[System.Serializable]
|
|||
|
public class NodeRuntimeData : IDisposable {
|
|||
|
[NonSerialized]
|
|||
|
protected Node node;
|
|||
|
|
|||
|
[NonSerialized]
|
|||
|
protected NodeRuntimeData parentNodeRuntimeData;
|
|||
|
|
|||
|
[NonSerialized]
|
|||
|
protected List<NodeRuntimeData> childNodeRuntimeData = new List<NodeRuntimeData>();
|
|||
|
|
|||
|
[SerializeField]
|
|||
|
public string logString = "";
|
|||
|
|
|||
|
[NonSerialized]
|
|||
|
public bool taskHasChanges = false;
|
|||
|
|
|||
|
public IEnumerator<NodeResult> tickExecuteEnumerator = null;
|
|||
|
|
|||
|
// only used for debugging, no actual function
|
|||
|
public int currentIndex = -1;
|
|||
|
|
|||
|
#if UNITY_EDITOR && false
|
|||
|
// debug version of result & state, slower
|
|||
|
[SerializeField]
|
|||
|
private NodeResult _nodeResult;
|
|||
|
public NodeResult nodeResult {
|
|||
|
get {
|
|||
|
return _nodeResult;
|
|||
|
}
|
|||
|
set {
|
|||
|
_nodeResult = value;
|
|||
|
if (node != null)
|
|||
|
if (node.debugInternalActive)
|
|||
|
Debug.Log(node.NodeLogger("nodeResultSet", $"set Node Result '{value}'"));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
[SerializeField]
|
|||
|
private NodeState _nodeState = NodeState.NotRunning;
|
|||
|
public NodeState nodeState {
|
|||
|
get {
|
|||
|
return _nodeState;
|
|||
|
}
|
|||
|
set {
|
|||
|
_nodeState = value;
|
|||
|
if (node != null)
|
|||
|
if (node.debugInternalActive)
|
|||
|
Debug.Log(node.NodeLogger("nodeStateSet", $"set Node State '{value}'"));
|
|||
|
}
|
|||
|
}
|
|||
|
#else
|
|||
|
// more performant solution for runtime
|
|||
|
public NodeResult nodeResult;
|
|||
|
public NodeState nodeState = NodeState.NotRunning;
|
|||
|
#endif
|
|||
|
public IEnumerator<NodeResult>[] subTickExecuteEnumerators = null;
|
|||
|
public NodeResult[] childResults;
|
|||
|
|
|||
|
public NodeRuntimeData (Node _node, NodeRuntimeData _parentNodeRuntimeData) {
|
|||
|
node = _node;
|
|||
|
parentNodeRuntimeData = _parentNodeRuntimeData;
|
|||
|
if (node.debugChangesActive) UnityEngine.Debug.Log(node.NodeLogger("NodeRuntimeData.Constructor", $""));
|
|||
|
node.nodeRuntimeDataList.Add(this);
|
|||
|
// root has no parent
|
|||
|
if (parentNodeRuntimeData != null) {
|
|||
|
parentNodeRuntimeData.childNodeRuntimeData.Add(this);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
~NodeRuntimeData() {
|
|||
|
if (node.debugChangesActive) UnityEngine.Debug.Log(node.NodeLogger("NodeRuntimeData.Destructor", $""));
|
|||
|
Dispose(false);
|
|||
|
}
|
|||
|
|
|||
|
public virtual void Destroy() {
|
|||
|
if ((node != null) && (node.debugInternalActive)) { Debug.Log($"NodeRuntimeData.Destroy {node}"); } else { }; // node can be null
|
|||
|
|
|||
|
if (childNodeRuntimeData != null) {
|
|||
|
for (int i= childNodeRuntimeData.Count-1; i>-1; i--) {
|
|||
|
childNodeRuntimeData[i].Destroy();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (node != null) {
|
|||
|
switch (node.GetType().ToString()) {
|
|||
|
case "MyBT.RunTreeNode":
|
|||
|
node.PreTick(NodeExecute.Abort, this);
|
|||
|
//cn2.node.Execute(this, NodeExecute.Abort);
|
|||
|
tickExecuteEnumerator.MoveNext();
|
|||
|
if (node.debugInternalActive) Debug.Log(node.NodeLogger($"NodeRuntimeData.Destroy", $"childNode result {tickExecuteEnumerator.Current}"));
|
|||
|
node.PostTick(NodeExecute.Abort, this);
|
|||
|
break;
|
|||
|
case "MyBT.ActionNode":
|
|||
|
node.Execute(this, NodeExecute.Abort);
|
|||
|
break;
|
|||
|
case "MyBT.CompositeNode":
|
|||
|
node.PreTick(NodeExecute.Abort, this);
|
|||
|
if (tickExecuteEnumerator != null) {
|
|||
|
tickExecuteEnumerator.MoveNext();
|
|||
|
}
|
|||
|
else if ((subTickExecuteEnumerators != null) && (subTickExecuteEnumerators.Length > 0)) {
|
|||
|
for (int j = 0; j < subTickExecuteEnumerators.Length; j++) {
|
|||
|
subTickExecuteEnumerators[j].MoveNext();
|
|||
|
}
|
|||
|
}
|
|||
|
else {
|
|||
|
//Debug.LogWarning($"{node} has no tick or subTick enumerator");
|
|||
|
}
|
|||
|
if (node.debugInternalActive) Debug.Log(node.NodeLogger($"NodeRuntimeData.Destroy", $""));
|
|||
|
node.PostTick(NodeExecute.Abort, this);
|
|||
|
break;
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
node.nodeRuntimeDataList.Remove(this);
|
|||
|
}
|
|||
|
|
|||
|
tickExecuteEnumerator = null;
|
|||
|
subTickExecuteEnumerators = null;
|
|||
|
nodeResult = NodeResult.Undefined;
|
|||
|
logString = "";
|
|||
|
parentNodeRuntimeData = null;
|
|||
|
childNodeRuntimeData = new List<NodeRuntimeData>();
|
|||
|
node = null;
|
|||
|
}
|
|||
|
|
|||
|
public virtual void Clear() {
|
|||
|
logString = "";
|
|||
|
}
|
|||
|
|
|||
|
// Flag: Has Dispose already been called?
|
|||
|
[System.NonSerialized]
|
|||
|
bool disposed = false;
|
|||
|
|
|||
|
// Public implementation of Dispose pattern callable by consumers.
|
|||
|
public void Dispose() {
|
|||
|
Dispose(true);
|
|||
|
GC.SuppressFinalize(this);
|
|||
|
}
|
|||
|
|
|||
|
// Protected implementation of Dispose pattern.
|
|||
|
protected virtual void Dispose(bool disposing) {
|
|||
|
if (disposed)
|
|||
|
return;
|
|||
|
|
|||
|
if (disposing) {
|
|||
|
// Free any other managed objects here.
|
|||
|
Destroy();
|
|||
|
}
|
|||
|
|
|||
|
// Free any unmanaged objects here.
|
|||
|
//
|
|||
|
|
|||
|
disposed = true;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|